题意
按规则出牌,问最少几步出完
题解
先考虑各种顺子,用顺子或不用顺子进行dfs
剩下的牌可贪心
调试记录
30分,每次memcpy的锅,不能每次memcpy,先把整个顺子找出来,然后从后面往前面减
95分,不能先贪心预处理,因为王可以扔进三带一、三带二、四带二里面去
然后2个王还不能当普通对子用
贪心还是要被卡2333
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstring>
#define maxn 25
#define INF 0x3f3f3f3f
using namespace std;
int n, cnt[maxn], ans;
const int id[14] = {0, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int c[maxn];
int calc(){
int tmp = INF;
int res = 0;
if (cnt[0] == 2){
memset(c, 0, sizeof c);
c[1] = 2;
for (int i = 1; i <= 13; i++) c[cnt[i]]++;
while (c[4] > 0 && c[1] > 1) c[4] -= 1, c[1] -= 2, res++;
while (c[4] > 0 && c[2] > 1) c[4] -= 1, c[2] -= 2, res++;
while (c[4] > 1) c[4] -= 2, res++;
while (c[4] > 0 && c[2] > 0) c[4] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[2] > 0) c[3] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[1] > 0) c[3] -= 1, c[1] -= 1, res++;
tmp = min(tmp, res + c[1] + c[2] + c[3] + c[4]);
res = 1; memset(c, 0, sizeof c);
for (int i = 1; i <= 13; i++) c[cnt[i]]++;
while (c[4] > 0 && c[1] > 1) c[4] -= 1, c[1] -= 2, res++;
while (c[4] > 0 && c[2] > 1) c[4] -= 1, c[2] -= 2, res++;
while (c[4] > 1) c[4] -= 2, res++;
while (c[4] > 0 && c[2] > 0) c[4] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[2] > 0) c[3] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[1] > 0) c[3] -= 1, c[1] -= 1, res++;
tmp = min(tmp, res + c[1] + c[2] + c[3] + c[4]);
}
else{
memset(c, 0, sizeof c);
for (int i = 0; i <= 13; i++) c[cnt[i]]++;
while (c[4] > 0 && c[1] > 1) c[4] -= 1, c[1] -= 2, res++;
while (c[4] > 0 && c[2] > 1) c[4] -= 1, c[2] -= 2, res++;
while (c[4] > 1) c[4] -= 2, res++;
while (c[4] > 0 && c[2] > 0) c[4] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[2] > 0) c[3] -= 1, c[2] -= 1, res++;
while (c[3] > 0 && c[1] > 0) c[3] -= 1, c[1] -= 1, res++;
tmp = min(tmp, res + c[1] + c[2] + c[3] + c[4]);
}
return tmp;
}
const int data[4] = {0, 5, 6, 6};
void dfs(int step){
if (step >= ans) return;
ans = min(ans, step + calc());
int tot, k;
for (int i = 2; i <= 13; i++){
for (int j = 3; j >= 1; j--){
if (cnt[i] >= j){
tot = 0;
for (k = i; k <= 13 && cnt[k] >= j; k++) cnt[k] -= j, tot += j;
for (; --k >= i; cnt[k] += j, tot -= j)
if (tot >= data[j]) dfs(step + 1);
}
}
}
}
int main(){
int T; scanf("%d%d", &T, &n);
while (T--){
memset(cnt, 0, sizeof cnt);
int pre = 0;
for (int color, x, i = 1; i <= n; i++){
scanf("%d%d", &x, &color);
cnt[id[x]]++;
}
ans = INF;
dfs(0);
printf("%d\n", pre + ans);
}
return 0;
}