题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461
这道题是一道很好的线性DP的题目,这种双头都可以选取的,可以运用带有头、尾位置信息的状态
dp[i][j] := 以第i位开头,第j位结尾的子问题的最优解
dp[i][j] = max(sum(i, i+k1) - dp[i+k1+1][j], sum(i, j-k2) - dp[i][j-k2-1]) (当 i <= j,注:i+k1 <= j && j - k2 >= i)
= 0 (当 i > j )
#include <cstdio> #include <iostream> #include <cstring> using namespace std; int a[105]; int dp[105][105]; int vis[105][105]; int f(int l, int r) { if(l > r) return 0; if(vis[l][r]) return dp[l][r]; int ret = 0, sum = 0; for(int i=l; i<=r; i++) ret += a[i]; for(int i=l; i<=r; i++) { sum += a[i]; ret = max(ret, sum - f(i+1, r)); } sum = 0; for(int i=r; i>=l; i--) { sum += a[i]; ret = max(ret, sum - f(l, i-1)); } vis[l][r] = 1; return dp[l][r] = ret; } int main () { int n; while(scanf("%d", &n) != EOF && n) { for(int i=0; i<n; i++) scanf("%d", &a[i]); memset(vis, 0, sizeof(vis)); printf("%d\n", f(0, n-1)); } return 0; }
时间: 2024-12-05 02:28:45