题目大意:有一系列的数字,两个人从这些数字中选择,可以从左选,也可以从右选,可以选1个以上,但是不能够左右两边同时选,选完数字后,求这两个人的差值是多少
解题思路:区间DP问题,设sum[i]为前i个数字的和,dp[i][j]为第i个数字到第j个数字的选择的最大和,则
dp[i][j] = sum[j] - sum[i-1] + min(dp[i+1][j],dp[i+2][j],...dp[i][j-2],dp[i][j-1]),min里面的是dp[i][j]的所有子区间,前面说了可以左右选择的,所以i+1到j的话就表示他选择了第i个,则dp[i+1][j]就是下一个人的最优选择了,那么sum[j]-sum[i-1] - MIN(区间内的最小值)就是这个人的最优选择了,右边的可以自己推,详细看代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF -0x3f3f3f3f
#define maxn 105
using namespace std;
int n,c[maxn],dp[maxn][maxn],sum[maxn];
int main() {
while(scanf("%d",&n) != EOF && n) {
sum[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%d",&c[i]);
sum[i] = sum[i-1] + c[i];
dp[i][i] = c[i];
}
for(int i = 1; i <= n; i++)
for(int j = 1; j + i <= n; j++) {
int k = j + i;
int ans = INF;
for(int l = j; l < k; l++) {
int m = min(dp[j][l],dp[l+1][k]);//dp[j][l]表示从右往左选择了第l+1到第k个,dp[l+1][k]表示从左往右选择了第j个到第l个,l+1表示不会出现dp[j][k]的那种不选择的状况
m = sum[k] - sum[j-1] - m;
if(ans < m)
ans = m;
}
if(ans < sum[k] - sum[j-1])
ans = sum[k] - sum[j-1];
dp[j][k] = ans;
}
printf("%d\n",dp[1][n]*2-sum[n]);
}
return 0;
}