http://www.elijahqi.win/archives/1376
题目描述
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x7f7f7f7f
#define N 20
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0;char ch=gc();
while (ch<'0'||ch>'9') ch=gc();
while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
return x;
}
int a[N],ans;
inline void calc(int step){
int tmp[5];int ans1=step;memset(tmp,0,sizeof(tmp));
for (int i=3;i<=16;++i) tmp[a[i]]++;int tt=0;
if (tmp[2]>=tmp[4]*2) ans1+=tmp[4],tt=tmp[4],tmp[4]=0,tmp[2]-=tt*2;else ans1+=tmp[2]>>1,tmp[4]-=tmp[2]>>1,tmp[2]-=tmp[2]>>1<<1;
if (tmp[1]>=tmp[4]*2) ans1+=tmp[4],tt=tmp[4],tmp[4]=0,tmp[1]-=tt*2;else ans1+=tmp[1]>>1,tmp[4]-=tmp[1]>>1,tmp[1]-=tmp[1]>>1<<1;
ans1+=min(tmp[4],tmp[2]); tt=tmp[4];tmp[4]-=min(tmp[4],tmp[2]);tmp[2]-=min(tt,tmp[2]);
ans1+=min(tmp[4],tmp[1]);tt=tmp[4];tmp[4]-=min(tmp[4],tmp[1]);tmp[1]-=min(tt,tmp[1]);
for (int i=3;i>=3;--i){
ans1+=min(tmp[i],tmp[2]);int tt=tmp[i];tmp[i]-=min(tmp[i],tmp[2]);tmp[2]-=min(tt,tmp[2]);
ans1+=min(tmp[i],tmp[1]);tt=tmp[i];tmp[i]-=min(tmp[i],tmp[1]);tmp[1]-=min(tt,tmp[1]);
} ans1+=tmp[4];ans1+=tmp[3];ans1+=tmp[2];ans1+=tmp[1];
ans=min(ans,ans1);
}
void dfs(int n,int step){
bool flag=0;int q[20],top=0;
//case单顺
for (int i=3;i<=10;++i){
for (int j=i;j<=14;++j){
if (a[j]>0) {
a[j]--;q[++top]=j;if (j-i+1>=5) dfs(n-(j-i+1),step+1),flag=1;
}else break;
}
while (top) a[q[top--]]++;
}top=0;
//case 双顺
for (int i=3;i<=12;++i){
for (int j=i;j<=14;++j){
if (a[j]>1) {
a[j]-=2;q[++top]=j;if (j-i+1>=3) dfs(n-(j-i+1),step+1),flag=1;
}else break;
}
while (top) a[q[top--]]+=2;
}top=0;
//case 三顺
for (int i=3;i<=12;++i){
for (int j=i;j<=14;++j){
if (a[j]>2) {
a[j]-=3;q[++top]=j;if (j-i+1>=2) dfs(n-(j-i+1),step+1),flag=1;
}else break;
}
while (top) a[q[top--]]+=3;
}top=0;
calc(step);
}
int n,T;
int main(){
// freopen("landlords.in","r",stdin);
T=read();n=read();
while (T--){
memset(a,0,sizeof(a));
for (int i=1;i<=n;++i){
int x=read(),xx=read();if (!x) a[16]++;
if (x==1) a[14]++;if (x==2) a[15]++;if (x&&x!=1&&x!=2) a[x]++;
}ans=inf;
dfs(n,0);printf("%d\n",ans);
}
return 0;
}