UVA 10891 Game of Sum(区间DP)
2017-07-26 18:39
417 查看
Game of Sum
思路:
dp[i][j]表示在区间i~j内先手所能获得的最大利益;
ls[i][j]表示先手从左边拿完后,在剩下的区间i~j内,后手所能获得的最小利益;
rs[i][j]表示先手从右边拿完后,在剩下的区间i~j内,后手所能获得的最小利益;
则dp[i][j]=sum[i][j]-min(min(ls[i+1][j],rs[i][j-1]),0);
解释一下上述式子,先手拿共有三种情况:
1.从左边拿1个,则后手剩余ls[i+1][j]
2.从右边拿1个,则后手剩余rs[i][j-1]
3.直接拿完,后手剩余0
问:为什么只拿一个?
答:ls[i][j]=min(dp[i][j],ls[i+1][j]);
rs[i][j]=min(dp[i][j],rs[i][j-1]);
一个只是形式上的一个,因为ls[i][j]和rs[i][j]在动态地更新最小值,也就是说
dp[i][j]=sum[i][j]-min(min(ls[i+1][j],rs[i][j-1]),0)得到的是在区间i~j内拿k(1<=k<=j-i)个的最大利益
最后答案ans=dp[1]
-(sum[1]
-dp[1]
)=2*dp[1]
-sum[1]
(具体详见代码)
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[110][110],sum[110],ls[110][110],rs[110][110]; int n; int main() { int x; while(~scanf("%d",&n),n) { for(int i=1; i<=n; ++i) { scanf("%d",&x); sum[i]=sum[i-1]+x; dp[i][i]=ls[i][i]=rs[i][i]=x; } for(int l=1; l<n; ++l) { for(int i=1; i<=n-l; ++i) { int j=i+l; dp[i][j]=sum[j]-sum[i-1]-min(min(ls[i+1][j],rs[i][j-1]),0); ls[i][j]=min(dp[i][j],ls[i+1][j]); rs[i][j]=min(dp[i][j],rs[i][j-1]); } } printf("%d\n",2*dp[1] -sum ); } return 0; }
看不懂?没关系,下面有个简单的
代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[110][110],sum[110]; int n; int main() { int x; while(~scanf("%d",&n),n) { for(int i=0; i<=n; ++i) for(int j=0; j<=n; ++j) dp[i][j]=-999999999; for(int i=1; i<=n; ++i) { scanf("%d",&x); sum[i]=sum[i-1]+x; dp[i][i]=x; } for(int l=1; l<n; ++l) //区间间隔 for(int i=1; i+l<=n; ++i) //起点 { int j=i+l;//终点 for(int k=i; k<j; ++k) //先手拿1~n-1的情况 dp[i][j]=max(dp[i][j],sum[j]-sum[i-1]-min(dp[i][k],dp[k+1][j]));//从左边拿,从右边拿 dp[i][j]=max(dp[i][j],sum[j]-sum[i-1]);//先手拿完的情况 } printf("%d\n",2*dp[1] -sum ); } return 0; }
相关文章推荐
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum (区间DP)
- UVA 10891 Game of Sum(区间DP)
- uva_10891 - Game of Sum( 博弈区间DP )
- UVA - 10891 Game of Sum (区间DP)@
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- Uva 10891 - Game of Sum ( 区间dp )
- uva 10891 - Game of Sum(博弈,区间dp)
- UVa 10891 Game of Sum (区间DP&博弈)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间博弈dp)***
- UVa 10891 Game of Sum(博弈区间DP)
- UVA - 10891 Game of Sum(区间dp)
- UVA 10891 Game of Sum(区间DP)
- UVA 10891 Game of Sum(区间DP)
- UVA - 10891 Game of Sum(记忆化搜索 区间dp)
- uva10891 Game of Sum 博弈区间dp
- Uva 10891 Game of Sum(区间博弈dp)
- UVA 10891 Game of Sum(区间DP)