uva 10118 - Free Candies(记忆化搜索)

题目大意:10118 - Free Candies


题目大意:有4堆糖果, 每堆糖果有n颗糖果,然后给出每颗糖果的类型1~20,然后只有取走当前堆的前面一颗糖果后才可以取后面的糖果, 然后小伙伴有一个篮子,篮子可以装5个糖果,如果篮子中的糖果存在相同类型的两个糖果,便可以将这两颗糖果算成一对放进腰包,问,小伙伴按什么样的方式取糖果可以取到最多的糖果。


解题思路:记忆化搜索,开一个四维数组记录当前4堆糖果取走相应个数后能拿到的最多对糖果数。


思路很简单,这也多亏了前一段时间坚持把小白的递归刷完。


#include <stdio.h>
#include <string.h>
#define max(a,b) (a)>(b)?(a):(b)
const int N = 50;
const int M = 5;

int n, g[N][M], dp[N][N][N][N];

void init() {
	memset(dp, -1, sizeof(dp));
	memset(g, 0, sizeof(g));
	for (int i = 0; i < n; i++)
		for (int j = 0; j < 4; j++) 
			scanf("%d", &g[i][j]);
}

int solve(int num[], int rec[], int cnt) {
	int& ans = dp[num[0]][num[1]][num[2]][num[3]];
	if (ans > -1) return ans;
	ans = 0;
	if (cnt == 5) return ans;

	for (int i = 0; i < 4; i++) {
		if (num[i] == n) continue;
		int t = g[num[i]][i];
		if (rec[t]) {
			rec[t] = 0, num[i]++;
			ans = max(ans, solve(num, rec, cnt - 1) + 1);
			rec[t] = 1, num[i]--;
		}
		else {
			rec[t] = 1, num[i]++;
			ans = max(ans, solve(num, rec, cnt + 1));
			rec[t] = 0, num[i]--;
		}
	}
	return ans;
}

int main() {
	while (scanf("%d", &n), n) {
		init();

		int num[M], rec[N];
		memset(rec, 0, sizeof(rec));
		memset(num, 0, sizeof(num));

		printf("%d\n", solve(num, rec, 0));
	}
	return 0;
}


你可能感兴趣的:(uva 10118 - Free Candies(记忆化搜索))