好,终于搞完了这一道毒瘤题......
先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索。
先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌。
大体思路很简单,写起来很毒瘤...
注意很多细节...我就是一个地方没写上界导致数组越界了。
三带一别带自己,因为可以算在4不带里。
王可以当对子出,当单牌带,但是不能当对牌带。
4带2对是存在的。
王的读入是0 1和0 2,中间有空格...
函数调用我写的很多,复制粘贴时别写混了。
变量++找牌的时候,要规定上界。
大概就是这些了。
代码6K...
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 const int N = 30; 5 6 int n, ans; 7 int bin[300000]; 8 9 inline void out() { 10 for(int i = 3; i <= 15; i++) { 11 printf("%3d", bin[i]); 12 } 13 printf("%3d ", bin[1]); 14 return; 15 } 16 17 inline void read() { 18 int x; 19 scanf("%d", &x); 20 if(x) { 21 if(x < 3) { 22 x += 13; 23 } 24 bin[x]++; 25 } 26 else { 27 bin[1]++; 28 } 29 scanf("%d", &x); 30 return; 31 } 32 void DFS(int, int, int); 33 34 void one_link(int rest, int time, int t, int pos) { 35 int l = std::max(pos, 3); 36 while(!bin[l] && l <= 15) { 37 l++; 38 } 39 if(l >= 11) { 40 DFS(rest, time, t + 1); 41 return; 42 } 43 int r = l + 1; 44 while(r < 15 && bin[r]) { 45 r++; 46 } 47 48 if(r - l >= 5) { 49 for(int j = l + 5; j <= r; j++) { 50 for(int i = l; i < j; i++) { 51 bin[i]--; 52 } 53 one_link(rest - (j - l), time + 1, t, l); 54 for(int i = l; i < j; i++) { 55 bin[i]++; 56 } 57 } 58 } 59 one_link(rest, time, t, l + 1); 60 return; 61 } 62 63 void two_link(int rest, int time, int t, int pos) { 64 int l = std::max(pos, 3); 65 while(bin[l] < 2 && l <= 15) { 66 l++; 67 } 68 if(l >= 13) { 69 DFS(rest, time, t + 1); 70 return; 71 } 72 int r = l + 1; 73 while(r < 15 && bin[r] > 1) { 74 r++; 75 } 76 77 if(r - l >= 3) { 78 for(int j = l + 3; j <= r; j++) { 79 /// [l, j) 80 for(int i = l; i < j; i++) { 81 bin[i] -= 2; 82 } 83 two_link(rest - 2 * (j - l), time + 1, t, l); 84 for(int i = l; i < j; i++) { 85 bin[i] += 2; 86 } 87 } 88 } 89 two_link(rest, time, t, l + 1); 90 return; 91 } 92 93 void three_link(int rest, int time, int t, int pos) { 94 int l = std::max(pos, 3);; 95 while(bin[l] < 3 && l <= 15) { 96 l++; 97 } 98 if(l >= 14) { 99 DFS(rest, time, t + 1); 100 return; 101 } 102 int r = l + 1; 103 while(r < 15 && bin[r] > 2) { 104 r++; 105 } 106 107 if(r - l >= 2) { 108 for(int j = l + 2; j <= r; j++) { 109 /// [l, j) 110 for(int i = l; i < j; i++) { 111 bin[i] -= 3; 112 } 113 three_link(rest - 3 * (j - l), time + 1, t, l); 114 for(int i = l; i < j; i++) { 115 bin[i] += 3; 116 } 117 } 118 if(r - l > 2) { 119 three_link(rest, time, t, l + 1); 120 } 121 else { 122 three_link(rest, time, t, r + 1); 123 } 124 } 125 else { 126 three_link(rest, time, t, r + 1); 127 } 128 return; 129 } 130 131 void four_four(int rest, int time, int t, int pos) { 132 int p = std::max(pos, 3); 133 while(bin[p] < 4 && p <= 15) { 134 p++; 135 } 136 if(p == 16) { 137 DFS(rest, time, t + 1); 138 return; 139 } 140 bin[p] -= 4; 141 for(int i = 3; i <= 15; i++) { 142 if(bin[i] > 1) { 143 bin[i] -= 2; 144 for(int j = i; j <= 15; j++) { 145 if(bin[j] > 1) { 146 bin[j] -= 2; 147 four_four(rest - 8, time + 1, t, p); 148 bin[j] += 2; 149 } 150 } 151 bin[i] += 2; 152 } 153 } 154 bin[p] += 4; 155 four_four(rest, time, t, p + 1); 156 return; 157 } 158 159 void four_two(int rest, int time, int t, int pos) { 160 int p = std::max(pos, 3); 161 while(bin[p] < 4 && p <= 15) { 162 p++; 163 } 164 if(p == 16) { 165 DFS(rest, time, t + 1); 166 return; 167 } 168 bin[p] -= 4; 169 for(int i = 1; i <= 15; i++) { 170 if(bin[i]) { 171 bin[i]--; 172 for(int j = i; j <= 15; j++) { 173 if(bin[j]) { 174 bin[j]--; 175 four_two(rest - 6, time + 1, t, p); 176 bin[j]++; 177 } 178 } 179 bin[i]++; 180 } 181 } 182 bin[p] += 4; 183 four_two(rest, time, t, p + 1); 184 return; 185 } 186 187 void three_two(int rest, int time, int t, int pos) { 188 int p = std::max(3, pos); 189 while(bin[p] < 3 && p <= 15) { 190 p++; 191 } 192 if(p == 16) { 193 DFS(rest, time, t + 1); 194 return; 195 } 196 bin[p] -= 3; 197 for(int i = 3; i <= 15; i++) { 198 if(bin[i] > 1) { 199 bin[i] -= 2; 200 three_two(rest - 5, time + 1, t, p); 201 bin[i] += 2; 202 } 203 } 204 bin[p] += 3; 205 three_two(rest, time, t, p + 1); 206 return; 207 } 208 209 void three_one(int rest, int time, int t, int pos) { 210 int p = std::max(pos, 3); 211 while(bin[p] < 3 && p <= 15) { 212 p++; 213 } 214 if(p == 16) { 215 DFS(rest, time, t + 1); 216 return; 217 } 218 bin[p] -= 3; 219 for(int i = 1; i <= 15; i++) { 220 if(bin[i] && i != p) { 221 bin[i]--; 222 three_one(rest - 4, time + 1, t, p); 223 bin[i]++; 224 } 225 } 226 bin[p] += 3; 227 three_one(rest, time, t, p + 1); 228 return; 229 } 230 231 void DFS(int rest, int time, int t) { 232 if(!rest) { 233 ans = std::min(ans, time); 234 return; 235 } 236 if(time >= ans - 1) { 237 return; 238 } 239 if(!t) { 240 one_link(rest, time, t, 0); 241 } 242 else if(t == 1) { 243 two_link(rest, time, t, 0); 244 } 245 else if(t == 2) { 246 three_link(rest, time, t, 0); 247 } 248 else if(t == 3) { 249 four_four(rest, time, t, 0); 250 } 251 else if(t == 4) { 252 four_two(rest, time, t, 0); 253 } 254 else if(t == 5) { 255 three_two(rest, time, t, 0); 256 } 257 else if(t == 6) { 258 three_one(rest, time, t, 0); 259 } 260 else { 261 int a = 0; 262 for(int i = 1; i <= 15; i++) { 263 a += (bin[i] > 0); 264 } 265 ans = std::min(ans, time + a); 266 } 267 return; 268 } 269 270 inline void solve() { 271 ans = 0; 272 for(int i = 1; i <= 15; i++) { 273 ans += (bin[i] > 0); 274 } 275 DFS(n, 0, 0); 276 printf("%d ", ans); 277 return; 278 } 279 280 int main() { 281 int T; 282 scanf("%d%d", &T, &n); 283 while(T--) { 284 for(int i = 1; i <= n; i++) { 285 read(); 286 } 287 solve(); 288 if(T) { 289 memset(bin, 0, sizeof(bin)); 290 } 291 } 292 293 return 0; 294 }
顺手把增强版也A了,跑的贼快。
数组300000是之前调的,忘了改回来。