题目:
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; }
本文介绍了一种利用线性动态规划(DP)解决包含双头选择情况的问题。通过定义状态转移方程,作者详细解释了如何计算以特定位置为开始和结束的最优解。同时,提供了一个具体的实例和代码实现,展示了从输入到输出的完整过程。

被折叠的 条评论
为什么被折叠?



