【解题报告】洛谷P2668 斗地主
题目链接
https://www.luogu.com.cn/problem/P2668
思路
大模拟+搜索
按照从顺子开始的顺序贪心,从三顺子先出,到双顺子,然后到顺子
然后出四带二,三带二,三带一,然后最后就是可以一次出完的那种了
这个题目呢贪心的思路想到不难,但是模拟出来及其考察代码能力
所以我就炸了
我代码能力超蒻的好不好
那是不是今年再出一个大模拟我就炸了
还有一个点就在于回溯
我们每次搜进去之后记得出来的时候回溯,以便搜索其他的状态,这样就比较方便了
强烈建议多练大模拟
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
| #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #define int long long using namespace std; int T,n,ans; int a[20]; void dfs(int x) { if(x>=ans) return ; int k=0; for(int i=3;i<=14;i++) { if(a[i]==0) k=0; else { k++; if(k>=5) { for(int j=i;j>=i-k+1;j--) a[j]--; dfs(x+1); for(int j=i;j>=i-k+1;j--) a[j]++; } } } k=0; for(int i=3;i<=14;i++) { if(a[i]<=1) k=0; else { k++; if(k>=3) { for(int j=i;j>=i-k+1;j--) a[j]-=2; dfs(x+1); for(int j=i;j>=i-k+1;j--) a[j]+=2; } } } k=0; for(int i=3;i<=14;i++) { if(a[i]<=2) k=0; else { k++; if(k>=2) { for(int j=i;j>=i-k+1;j--) a[j]-=3; dfs(x+1); for(int j=i;j>=i-k+1;j--) a[j]+=3; } } } for(int i=2;i<=14;i++) { if(a[i]<=3) { if(a[i]<=2) continue; a[i]-=3; for(int j=2;j<=15;j++) { if(a[j]<=0||j==i) continue; a[j]--; dfs(x+1); a[j]++; } for(int j=2;j<=14;j++) { if(a[j]<=1||j==i) continue; a[j]-=2; dfs(x+1); a[j]+=2; } a[i]+=3; } else { a[i]-=3; for(int j=2;j<=15;j++) { if(a[j]<=0||j==i) continue; a[j]--; dfs(x+1); a[j]++; } for(int j=2;j<=14;j++) { if(a[j]<=1||j==i) continue; a[j]-=2; dfs(x+1); a[j]+=2; } a[i]+=3; a[i]-=4; for(int j=2;j<=15;j++) { if(a[j]<=0||j==i) continue; a[j]--; for(int k=2;k<=15;k++) { if(a[k]<=0||k==j) continue; a[k]--; dfs(x+1); a[k]++; } a[j]++; } for(int j=2;j<=14;j++) { if(a[j]<=1||j==i) continue; a[j]-=2; for(int k=2;k<=14;k++) { if(a[k]<=1||k==j) continue; a[k]-=2; dfs(x+1); a[k]+=2; } a[j]+=2; } a[i]+=4; } } for(int i=1;i<=15;i++) { if(a[i]) x++; } ans=min(ans,x); } signed main() { cin>>T>>n; while(T--) { ans=1e9; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) { int x,y; cin>>x>>y; if(x==0) a[15]++; else if(x==1) a[14]++; else a[x]++; } dfs(0); cout<<ans<<'\n'; } return 0; }
|