首页 > 代码库 > XTU OJ 1168 Alice and Bob (二维dp)
XTU OJ 1168 Alice and Bob (二维dp)
Alice and Bob | ||
Accepted : 98 | Submit : 324 | |
Time Limit : 1000 MS | Memory Limit : 65536 KB |
Problem DescriptionAlice and Bob always love to play games, so does this time. InputMultiple test cases. First line, there is an integer T ( 1 ≤ T ≤ 20 ), indicating the number of test cases. OuputFor each test case, output a line. It is an integer number k, indicating the least number of operation in need to finish the task. Sample Input5 1 2 3 4 5 Sample Output1 1 2 1 2 SourceXTU OnlineJudge 去年看到这道题目的时候对动态规划没有一点思路,不知道该怎么往那方面想,对动态规划有种畏惧的感觉。重新来做这道题目,往那方面想还是得不出递推方程式啊,动态规划还是得多练,还需要有一定的灵感;看了一下别人的思路,终于看懂了,http://blog.csdn.net/libin56842/article/details/26287101 用自己的风格写了一遍; 这里用的是二维dp,用dp[i][0]:alice 取i颗石子所用的最小步数(alice是先手); dp[i][1]:bob 取i颗石子所用的最小步数; alice先取石子,如果alice一次没有取完,bob就接着取,我们要得到的是取完所用的最小步数,所以我们可以得到状态关系式; min(dp[i][0],dp[i-j][1]+1); j就是Alice取走的颗数,bob接着取次数就要加1; 下面是代码: #include <cstdio> #include <cstring> #define min(a,b) a<b?a:b const int maxn=10005; const int Max=0x3f3f3f3f; int dp[maxn][2]; int main() { int t,n,i,j; dp[0][0] = dp[0][1] = 0; dp[1][0]=dp[1][1]=dp[2][0]=1;//一次可以取完 dp[2][1]=2;//bob要取两次 for(i=3;i<maxn;i++)//这里我们就要从3开始了 { dp[i][0]=dp[i][1]=Max;//初始值赋为最大值 for(j=1;j<=i;j*=2)//alice每次取的是2的j次 dp[i][0]=min(dp[i][0],dp[i-j][1]+1);//比较直接的最小值 for(j=1;j<=i;j*=3)//bob取的 dp[i][1]=min(dp[i][1],dp[i-j][0]+1); } scanf("%d",&t); while(t--) { scanf("%d",&n); printf("%d\n",dp[n][0]);//这里按的是alice为先手算的 } return 0; } |