Problem Address:http://acm.zjut.edu.cn/ShowProblem.aspx?ShowID=1420
DP题,参照了之前的一道题:http://blog.youkuaiyun.com/Human_CK/archive/2011/02/17/6191860.aspx,理解后修改了几个地点,居然写出了第一道有点模样的DP,哈哈哈!
这道题不是左右轮流取,而是左或右取完一个后必须被另一个人去掉一个,而那个人取的时候会采取最有策略。
所以取左或取右之后得判断下一步被取完之后的最小值。
代码如下:
#include <iostream>
using namespace std;
int dp[105][105];
int min(int a, int b)
{
if (a<=b) return a;
else return b;
}
int search(int L, int R)
{
if (L>R) return 0;
if (dp[L][R]!=-1) return dp[L][R];
int a = min(search(L+2, R), search(L+1, R-1)) + dp[L][L];
int b = min(search(L, R-2), search(L+1, R-1)) + dp[R][R];
dp[L][R] = a>=b?a:b;
return dp[L][R];
}
int main()
{
int n,i,j,sum;
scanf("%d", &n);
while(scanf("%d", &n)!=EOF)
{
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
dp[i][j] = -1;
sum = 0;
for (i=1; i<=n; i++)
{
scanf("%d", &dp[i][i]);
sum += dp[i][i];
}
n = search(1, n);
printf("%d %d/n", n, sum-n);
}
return 0;
}
本文解析了一道DP博弈问题,该问题要求玩家从两端取数,另一玩家则采取最优策略移除一个数。通过递归搜索并记录状态,实现了有效的动态规划解决方案。
1563

被折叠的 条评论
为什么被折叠?



