动态规划做,用数组判断糖果是否在篮子里
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 42;
int d[MAXN][MAXN][MAXN][MAXN]; // 记录每种情况下的结果
int n; // 每一堆糖果的个数
int C[MAXN][4]; // 4堆糖果的放法
int num[4]; // 每一堆糖果已经使用过的情况
bool vis[MAXN][MAXN][MAXN][MAXN]; // 判断这个情况是否已经存在过
bool ext[21]; // 判断该糖果是否存在
// cur是糖果的个数
int dp (int cur) {
if (vis[num[0]][num[1]][num[2]][num[3]]) return d[num[0]][num[1]][num[2]][num[3]];
vis[num[0]][num[1]][num[2]][num[3]] = true;
int &ans = d[num[0]][num[1]][num[2]][num[3]];
ans = 0;
for (int i = 0; i < 4; i++) {
if (num[i] >= n || cur > 4 || (cur == 4 && !ext[C[num[i]][i]])) continue; // 第i堆已经没有糖果可以放了
// 判断d是否可以增加一对
ext[C[num[i]][i]] = !ext[C[num[i]][i]];
num[i]++;
if (!ext[C[num[i]-1][i]]) {
ans = max(ans, dp(cur-1)+1);
} else {
ans = max(ans, dp(cur+1));
}
num[i]--;
ext[C[num[i]][i]] = !ext[C[num[i]][i]];
}
return ans;
}
bool read () {
scanf("%d", &n);
if (n == 0) return false;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 4; j++) {
scanf("%d", &C[i][j]);
}
}
memset(vis, 0, sizeof(vis));
memset(ext, 0, sizeof(ext));
num[0] = num[1] = num[2] = num[3] = 0;
return true;
}
int main () {
while (read()) {
dp(0);
printf("%d\n", d[0][0][0][0]);
}
return 0;
}