您的位置:首页 > 其它

UVa 10118 免费糖果(记忆化搜索+哈希)

2017-02-08 14:10 134 查看
https://vjudge.net/problem/UVA-10118

题意:

桌上有4堆糖果,每堆有N颗。佳佳有一个最多可以装5颗糖的小篮子。他每次选择一堆糖果,把最顶上的一颗拿到篮子里。如果篮子里有两颗颜色相同的糖果,佳佳就把它们从篮子里拿出来放到自己的口袋里。如果篮子满了而里面又没有相同颜色的糖果,游戏结束。

思路:

怎么判断糖果是否颜色相同是本题的一个重点,看了别人的思路后明白了用哈希是很好的办法。

因为一共只有20颗种类的糖果,所以只需要一个20大小的数组来判断糖果是否出现过。

top[5]数组用来标记每堆糖果所拿的个数。

#include<iostream>
#include<string>
#include<cstring>
#include<sstream>
#include<algorithm>
using namespace std;

const int maxn = 45;

int n;
int c[4][maxn];
int d[maxn][maxn][maxn][maxn];
int top[5];
bool Hash[25];

int dp(int cur)
{
int& ans = d[top[0]][top[1]][top[2]][top[3]];
if (ans)  return ans;
if (cur == 5)  return 0;   //篮子满了
for (int i = 0; i < 4; i++)
{
if (top[i] == n)  continue;   //已经取完
int x = c[i][top[i]++];
if (Hash[x] == true)
{
Hash[x] = false;
ans = max(ans, dp(cur - 1) + 1);
Hash[x] = true;
}
else
{
Hash[x] = true;
ans = max(ans, dp(cur + 1));
Hash[x] = false;
}
top[i]--;
}
return ans;
}

int main()
{
//freopen("D:\\txt.txt", "r", stdin);
while (cin >> n && n)
{
memset(d, 0, sizeof(d));
memset(top, 0, sizeof(top));
memset(Hash, false, sizeof(Hash));
for (int i = 0; i < n;i++)
for (int j = 0; j < 4; j++)
cin >> c[j][i];
cout << dp(0) << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: