[每日N题] 3.31 Free Candies UVA - 10118 [动态规划]

Free Candies UVA - 10118

动态规划做,用数组判断糖果是否在篮子里

#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;
}

猜你喜欢

转载自blog.csdn.net/AdamAndTina/article/details/88928451