100道动态规划——5 UVA 10118 Free Candies 记忆化搜索 以及 证明状态
2016-10-30 12:39
701 查看
好吧,这道题目我没想出来。。。这道题我觉得和我之前做过的一道题目有点像,100道动态规划3 UVA 1625 http://blog.csdn.net/good_night_sion_/article/details/52918040 都是从顶部拿一些东西出来,只不过是代价函数不同而已。根据那道题目的思想,这道题的状态定义至少是4维的——需要把4个堆的顶部拿了多少个元素的这个状态包含进来。然后我就一直纠结这样一个问题,在1,2,3,4个堆分别拿了i,j,k,l个糖果的时候篮子里面的糖果数量以及颜色是不是唯一的。因为这个问题的答案将会涉及到我的数组还要再开几维的问题。至于是采用记忆化搜索还是递推或者刷表的问题,我觉得在这道题目上采用记忆化搜索是比较合适的,原因是在我们把0,0,0,0作为起点的情况下,末状态不是很好确定。而递推和刷表都是采用循环的方式,将跑到很多无效的状态里面去。
接下来是我的证明,在1,2,3,4个堆拿了i,j,k,l的糖果的时候篮子里面的糖果数量和颜色是唯一的
假设存在两种不同的拿法使得拿了i,j,k,l颗糖果之后篮子里面的状态不一样,即此时一定存在一种拿法比另外一种拿法要多至少一种颜色,无妨设A拿法比B拿法多一种a颜色。
因为两种拿法都把i,j,k,l个糖果拿完了,因此每个颜色的糖果的总数是一样的。A拿法在拿完之后还剩下一个a颜色,因此a颜色的糖果必然是奇数的。但是B拿法也是在拿完之后没有a颜色,因此a颜色是偶数的。a颜色既是奇数又是偶数,矛盾。因此状态唯一。因此在定义状态的时候只需要4个下标即可唯一描述这个状态。
接下来是记忆化搜索的代码,pos代表在其顶部拿了多少个糖果,candy表示篮子里是不是有对应的糖果。dp[i][j][k][l]代表在其顶部拿了i,j,k,l个后最多还可以拿走多少对糖果
接下来是我的证明,在1,2,3,4个堆拿了i,j,k,l的糖果的时候篮子里面的糖果数量和颜色是唯一的
假设存在两种不同的拿法使得拿了i,j,k,l颗糖果之后篮子里面的状态不一样,即此时一定存在一种拿法比另外一种拿法要多至少一种颜色,无妨设A拿法比B拿法多一种a颜色。
因为两种拿法都把i,j,k,l个糖果拿完了,因此每个颜色的糖果的总数是一样的。A拿法在拿完之后还剩下一个a颜色,因此a颜色的糖果必然是奇数的。但是B拿法也是在拿完之后没有a颜色,因此a颜色是偶数的。a颜色既是奇数又是偶数,矛盾。因此状态唯一。因此在定义状态的时候只需要4个下标即可唯一描述这个状态。
接下来是记忆化搜索的代码,pos代表在其顶部拿了多少个糖果,candy表示篮子里是不是有对应的糖果。dp[i][j][k][l]代表在其顶部拿了i,j,k,l个后最多还可以拿走多少对糖果
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n,dp[45][45][45][45],arr[4][45],pos[4]; bool candy[25]; int search(int cnt); int main(){ while(scanf("%d",&n)&&n){ for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) for(int k=0;k<=n;++k) for(int l=0;l<=n;++l) dp[i][j][k][l]=-1; for(int i=0;i<n;++i) for(int j=0;j<4;++j) scanf("%d",&arr[j][i]); printf("%d\n",search(0)); pos[0]=pos[1]=pos[2]=pos[3]=0; } return 0; } int search(int cnt){ int &te=dp[pos[0]][pos[1]][pos[2]][pos[3]]; if(te!=-1) return te; if(cnt==5) return te=0; te=0; for(int i=0,color;i<4;++i){ if(pos[i]==n)continue; color=arr[i][pos[i]]; ++pos[i]; if(candy[color]){ candy[color]=false; te=max(te,search(cnt-1)+1); candy[color]=true; } else{ candy[color]=true; te=max(te,search(cnt+1)); candy[color]=false; } --pos[i]; } return te; }
相关文章推荐
- 100道动态规划——19 UVA 12105 Bigger is Better 状态的定义以及转移方程
- 100道动态规划——8 UVA 1631 Locker 递推,状态的定义以及状态转移方程
- 100道动态规划——34 UVA 10559 Blocks 状态的定义 状态转移方程
- 100道动态规划——22 POJ 1661 帮助 Jimmy 记忆化搜索 状态定义 以及一个思维上的漏洞
- 100道动态规划——26 UVA 12099 The Bookcase 状态的定义,递推,背包
- 100道动态规划——24 UVA 1633 Dyslexic Gollum 状态压缩DP 挺好的题 因为窝没想到嘛
- 100道动态规划——32 UVA 12170 Easy Climb 通过分析减少状态数 单调队列
- 100道动态规划——9 UVA 10723 Cyborg Genes LCS的应用以及有趣的题干
- 100道动态规划——30 UVAlive 3907 Puzzle AC自动机上的动态规划,记忆化搜索
- 100道动态规划——25 UVA 1204 Fun Game 状态压缩 圆圈的处理 (100道完成了1/4啦)
- UVa 10118 Free Candies (记忆化搜索+状态压缩)
- UVA - 10118 Free Candies(dfs+记忆化搜索)
- UVA 10118 - Free Candies(记忆化搜索)
- 100道动态规划——6 UVA 1629 Cake slicing 记忆化搜索
- 100道动态规划——1 UVA 1347 Tour 算法导论书后习题 双调巡游
- 100道动态规划——14 UVA 1412 Fund Management 从刘汝佳dalao的代码里学到了很多。。。。
- 100道动态规划——15 UVA 10618 Tango Tango Insurrection 复杂的转移方程。。
- 100道动态规划——4 UVA 1331 Maximum Triangulation DP 计算几何
- UVA10118_Free Candies状态压缩
- UVa 10118 - Free Candies(记忆化搜索)