LightOJ 1031 Easy Game--区间dp
原创
©著作权归作者所有:来自51CTO博客作者Limer123的原创作品,请联系作者获取转载授权,否则将追究法律责任
原题链接:http://vjudge.net/problem/LightOJ-1031
题意:n个数,两个人A和B每次从头部或尾部取出若干个数,直到取完,最后 ’A取出数和‘ 减去 ‘B取出数和’ ,使其最大,求这个最大值。
分析:dp[ i ][ j ]表示区间i,j内A-B的最大值。那么对于k(i<=k<j),分为[ i , k ]和[ k+1 , j ]两部分,如果A取[ i , k ],那么剩下的[ k+1 , j ]就是B先取,则dp[ k+1 ][ j ]表示B-A,那么整个dp[ i ][ j ]就是等于sum[k] - sum[i - 1] - dp[k + 1][j] = A-(A-B)。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<string>
#include<stdio.h>
#define INF 99999999
#define eps 0.0001
using namespace std;
int t;
int n;
int v[105];
int sum[105];
int dp[105][105];
int main()
{
scanf("%d", &t);
for (int cas = 1; cas <= t; cas++)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &v[i]);
sum[i] = sum[i - 1] + v[i];
dp[i][i] = v[i];
}
for (int l = 1; l <= n; l++)
{
for (int i = 1; i + l <= n; i++)
{
int j = i + l;
dp[i][j] = sum[j] - sum[i - 1];
for (int k = i; k < j; k++)
{
dp[i][j] = max(dp[i][j], sum[k] - sum[i - 1] - dp[k + 1][j]);
dp[i][j] = max(dp[i][j], sum[j] - sum[k] - dp[i][k]);
}
}
}
printf("Case %d: %d\n", cas, dp[1][n]);
}
return 0;
}