题目描述
牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的AAA到KKK加上大小王的共545454张牌来进行的扑克牌游戏。在斗地主中,牌的大小关 系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王3<4<5<6<7<8<9<10<J<Q<K<A<2< ext{小王}< ext{大王}3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由 nnn 张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。
现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。
需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。具体规则如下:
本题数据随机,不支持hack,要hack或强力数据请点击这里
-----------------------------------------------------------------------------------------------------------------
搜索经典题目。
没什么别的思路,就是dfs+贪心
总体策略:先打顺子再打三带最后打单牌和对子
坑点巨多,调了好久才调出来……
#include<bits/stdc++.h> using namespace std; int T,n,sum[25],ans,output[105]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); }while('0'<=ch&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } void dfs(int x) { if (x>=ans) return; int k=0; for (int i=3;i<=14;i++) { if (sum[i]==0) k=0; else{ k++; if (k>=5){ for (int j=i;j>=i-k+1;j--) sum[j]--; dfs(x+1); for (int j=i;j>=i-k+1;j--) sum[j]++; } } } k=0; for (int i=3;i<=14;i++) { if (sum[i]<=1) k=0; else { k++; if (k>=3) { for (int j=i;j>=i-k+1;j--) sum[j]-=2; dfs(x+1); for (int j=i;j>=i-k+1;j--) sum[j]+=2; } } } k=0; for (int i=3;i<=14;i++) { if (sum[i]<=2) k=0; else { k++; if (k>=2) { for (int j=i;j>=i-k+1;j--) sum[j]-=3; dfs(x+1); for (int j=i;j>=i-k+1;j--) sum[j]+=3; } } } for (int i=2;i<=14;i++) { if (sum[i]<=3) { if (sum[i]<=2) continue; sum[i]-=3; for (int j=2;j<=15;j++) { if (sum[j]<=0||j==i) continue; sum[j]--; dfs(x+1); sum[j]++; } for (int j=2;j<=14;j++) { if (sum[j]<=1||j==i) continue; sum[j]-=2; dfs(x+1); sum[j]+=2; } sum[i]+=3; } else { sum[i]-=3; for (int j=2;j<=15;j++) { if (sum[j]<=0||j==i) continue; sum[j]--; dfs(x+1); sum[j]++; } for (int j=2;j<=14;j++) { if (sum[j]<=1||j==i) continue; sum[j]-=2; dfs(x+1); sum[j]+=2; } sum[i]+=3; sum[i]-=4; for (int j=2;j<=15;j++) { if (sum[j]<=0||j==i) continue; sum[j]--; for (int h=2;h<=15;h++) { if (sum[h]<=0||j==h) continue; sum[h]--; dfs(x+1); sum[h]++; } sum[j]++; } for (int j=2;j<=14;j++) { if (sum[j]<=1||j==i) continue; sum[j]-=2; for (int h=2;h<=14;h++) { if (sum[h]<=1||h==j) continue; sum[h]-=2; dfs(x+1); sum[h]+=2; } sum[j]+=2; } sum[i]+=4; } } for (int i=2;i<=15;i++) if (sum[i]) x++; ans=min(ans,x); } int main() { T=read(),n=read();int ff=T; while(T--) { ans=0x7fffffff; int x,y; memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++) { x=read(),y=read(); if (x==0) sum[15]++; else if(x==1) sum[14]++; else sum[x]++; } dfs(0); cout<<ans<<endl; } }