题目链接:http://poj.org/problem?id=3186
题意:给一个数组v,每次可以取前面的或者后面的,第k次取的v[i]价值为v[i]*k,问总价值最大是多少。
区间dp。
设dp[i][j] 为 取i到j后 的最大值,可能由d[i+1][j]或者d[i][j-1]转移而来。
转移方程:dp[i][j]=max(dp[i+1][j]+p[i]*(n+i-j),dp[i][j-1]+p[j]*(n+i-j)); 其中n-(j-i)是第几次取
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int p[2010]; 6 int dp[2010][2010]; 7 int n; 8 9 int main() 10 { 11 while(scanf("%d",&n)!=EOF) 12 { 13 memset(dp,0,sizeof(dp)); 14 for(int i=1;i<=n;i++) 15 { 16 scanf("%d",&p[i]); 17 dp[i][i]=p[i]; 18 } 19 int ans=0; 20 for(int i=n;i>=1;i--) 21 for(int j=i;j<=n;j++) 22 { 23 dp[i][j]=max(dp[i+1][j]+p[i]*(n+i-j),dp[i][j-1]+p[j]*(n+i-j)); 24 } 25 printf("%d ",dp[1][n]); 26 } 27 }