爆搜+平时打斗地主的技巧就行了,该出什么就出什么。。。。。还是回去打斗地主吧。
#include<cstdio>
#include<cstring>
int cnt1[100],cnt2[100],t,n,ans;
const int len[]={0,5,3,2};
int solve(int x=0){
for(int i=0;i<=4;++i)cnt1[i]=0;
cnt1[5]=cnt2[0];
for(int i=1;i<=14;++i)cnt1[cnt2[i]]++;
for(;cnt1[4]>0&&cnt1[2]>1;cnt1[4]--,cnt1[2]-=2)x++;
for(;cnt1[4]>0&&cnt1[1]>1;cnt1[4]--,cnt1[1]-=2)x++;
for(;cnt1[3]>0&&cnt1[2]>0;cnt1[3]--,cnt1[2]--)x++;
for(;cnt1[3]>0&&cnt1[1]>0;cnt1[3]--,cnt1[1]--)x++;
for(;cnt1[4]>0&&cnt1[5]>1;cnt1[4]--,cnt1[5]=0)x++;
for(;cnt1[3]>0&&cnt1[5]>0;cnt1[3]--,cnt1[5]--)x++;
for(;cnt1[4]>0&&cnt1[2]>0;cnt1[4]--,cnt1[2]--)x++;
x+=cnt1[4]>>1;
for(int i=1;i<=4;++i)x+=cnt1[i];
if(cnt1[5])x++;
return x;
}
void dfs(int u){
int v,c=solve();
if(c+u<ans)ans=c+u;
for(int ch=1;ch<=3;ch++){
v=0;
for(int i=1;i<=13;++i){
for(int k=v;k<=i-len[ch]-1;++k){
for(int c=i-1;c>k;c--)cnt2[c]-=ch;
dfs(u+1);
for(int c=i-1;c>k;c--)cnt2[c]+=ch;
}
if(cnt2[i]<ch)v=i;
}
}
}
int main(){
scanf("%d%d",&t,&n);
while(t--){;
memset(cnt2,0,sizeof(cnt2));
ans=n;
for(int x1,x2,i=1;i<=n;++i){
scanf("%d%d",&x1,&x2);
x1?x1=(x1+10)%13+1:1;
cnt2[x1==13?14:x1]++;
}
dfs(0);
printf("%d\n",ans);
}
return 0;
}