Light OJ 1031 - Easy Game(区间dp)
Posted aiterator
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Light OJ 1031 - Easy Game(区间dp)相关的知识,希望对你有一定的参考价值。
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1031
题目大意:两个选手,轮流可以从数组的任意一端取值, 每次可以去任意个但仅限在一端, 他们的得分分别是取得所有值的和。现在求这两个选手得分差值的最大值。
解题思路:设dp[i][j]代表从i到j这个区间中,所能够得到的最大差值,只需要枚举其中i到j之间的一个数c,作为断电,那么最大值应该为max(sum[c]-sum[i-1]-dp[c+1][j], sum[j]-sum[c-1]-cou(i, c-1))。然后在更新这一个值就行了。
代码如下:
#include <bits/stdc++.h> using namespace std; const int N = 107; int sum[N], dp[N][N]; int cou(int i, int j) { if(i > j) return 0; if(dp[i][j] != INT_MAX) return dp[i][j]; dp[i][j] = sum[j] - sum[i-1]; for(int c=i; c<=j; ++ c) { dp[i][j] = max(dp[i][j], sum[c] - sum[i-1] - cou(c+1, j)); dp[i][j] = max(dp[i][j], sum[j] - sum[c-1] - cou(i, c-1)); } return dp[i][j]; } void solve(int cases) { int n; scanf("%d", &n); for(int i=1; i<=n; ++ i) for(int j=1; j<=n; ++ j) dp[i][j] = INT_MAX; sum[0] = 0; for(int i=1; i<=n; ++ i) { scanf("%d", &sum[i]); dp[i][i] = sum[i]; sum[i] += sum[i-1]; } printf("Case %d: %d\\n", cases, cou(1, n)); } int main() { int t; scanf("%d", &t); for(int i=1; i<=t; ++ i) solve(i); return 0; }
以上是关于Light OJ 1031 - Easy Game(区间dp)的主要内容,如果未能解决你的问题,请参考以下文章
Light OJ 1020 - A Childhood Game
LIGHT OJ 1199 - Partitioning Game
杭电OJ(HDU)-ACMSteps-Chapter Two-《An Easy Task》《Buildings》《decimal system》《Vowel Counting》