区间dp;
这道题我是在看了几份阶梯报告之后才想通的,现在想想很符合动态规划的要求
d(i, j)表示取数的人在数组i 到 j中能取的的最大值,然后中间枚举分割点,
ans = max(ans, sum[k]-sum[i-1]-d(k+1, j));
ans = max(ans, sum[j]-sum[k-1]-d(i, k-1));
采用和记忆化搜索的方式
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf = 99999999;
int dp[110][110], sum[110];
int d(int i, int j)
{
int &ans = dp[i][j];
if(ans > -inf)
return ans;
ans = sum[j] - sum[i-1];
for(int k=i; k<=j; k++)
{
ans = max(ans, sum[k]-sum[i-1]-d(k+1, j));
ans = max(ans, sum[j]-sum[k-1]-d(i, k-1));
}
return ans;
}
int main()
{
int t, ca = 1;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
sum[0] = 0;
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
dp[i][j] = -inf;
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", ca++, d(1, n));
}
return 0;
}