|
本帖最后由 lyc 于 2018-7-4 18:08 编辑
加强版数据太强了……疯狂特判(因为还有可以拆的牌,不过整体还是一样,改一下散牌)然而我之前漏了好多,,,debug好久,部分特判参考题解
- #include<cstdio>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- const int N = 20;
- using namespace std;
- int p[N],c[N];
- int n,t,ans;
- int other(){//打散牌
- int t = 0;
- int c[10]; bool boom = 0;//炸弹
- memset(c, 0, sizeof(c));
- if(p[0] == 2) boom = 1;
- c[1] += p[0];//王分开算
- for(int i=1; i<=13; i++) c[p[i]] ++;
- while(!c[3] && c[4] >= 2 && c[1] == 1 && c[2] == 1) c[4]-=2, c[1] --, c[2] --, t += 2;
- while(!c[3] && c[4] >= 2 && c[1] == 2 && c[2] == 2) c[4]-=2, c[1] -=2, c[2] -=2, t += 2;
- while(!c[2] && c[3] >= 2 && c[4] == 1 && c[1] == 1) c[3]-=2, c[1] --, c[4] --, t += 2;
- if(c[3] + c[4] > c[1] + c[2])
- while(c[4] && c[2] && c[3]) c[2]--, c[3]--, c[1]++, c[4]--,t++;
- if(c[3] + c[4] > c[1] + c[2])
- while(c[4] && c[1] && c[3]) c[1]--, c[3]--, c[2]++, c[4]--,t++;//以上拆牌打更优
- if(c[3] % 3 == 0 && c[1] + c[2] <= 1)//拆三张
- while(c[3] > 2) c[3] -= 3, t += 2;
- while(c[4] && c[2] >= 2) c[4] --, c[2] -= 2, t++;//四带二对
- while(c[4] && c[1] >= 2) c[4] --, c[1] -= 2, t++;//四带二
- while(c[4] && c[2] >= 1) c[4] --, c[2] -- , t++;//四带一对
- while(c[3] && c[2]) c[3] --, c[2] --, t++;
- while(c[3] && c[1]) c[3] --, c[1] --, t++;
- while(c[4] >= 2 && c[3]) c[4] -= 2, c[3] --, t+=2;
- while(c[3] >= 2 && c[4]) c[3] -= 2, c[4] --, t+=2;//拆三和炸弹
- while(c[3] >= 3) c[3] -= 3, t+=2;//三张三也能拆orz
- while(c[4] >= 2) c[4]-=2, t++;
- if(boom && c[1] >= 2) return t + c[1] + c[2] + c[3] + c[4] - 1;
- return t + c[1] + c[2] + c[3] + c[4];
- }
- void dfs(int now)
- {
- if(now >= ans)
- return ;
- int add = other();
- if(now + add < ans)
- ans = now + add;
- for(int i=2; i<=13; i++)
- {
- int j=i;
- while(p[j] >= 3)
- j++;
- if(j-i >= 2)
- {
- for(int m=i+1; m<=j-1; m++)
- {
- for(int k=i; k<=m; k++)
- p[k]-=3;
- dfs(now+1);
- for(int k=i; k<=m; k++)
- p[k]+=3;
- }
- }
- }
- for(int i=2; i<=13; i++)
- {
- int j=i;
- while(p[j]>=2)
- j++;
- if(j-i>=3)
- {
- for(int m=i+2; m<=j-1; m++)
- {
- for(int k=i; k<=m; k++)
- p[k]-=2;
- dfs(now+1);
- for(int k=i; k<=m; k++)
- p[k]+=2;
- }
- }
- }
- for(int i=2; i<=13; i++)
- {
- int j=i;
- while(p[j]>=1)
- j++;
- if(j-i>=3)
- {
- for(int m=i+4; m<=j-1; m++)
- {
- for(int k=i; k<=m; k++)
- p[k]--;
- dfs(now+1);
- for(int k=i; k<=m; k++)
- p[k]++;
- }
- }
- }
- }
- int main()
- {
- cin>>t>>n;
- while(t--)
- {
- memset(p,0,sizeof(p));
- for(int i=1; i<=n; i++)
- {
- int a, b;
- cin>>a>>b;
- if(a==1)
- a=13;
- else if(a)
- a--;
- p[a]++;
- }
- ans=n;
- dfs(0);
- cout<<ans<<endl;
- }
- return 0;
- }
复制代码 |
|