题目大意: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; }