POJ3186:Treats for the Cows(区间DP)

来源:互联网 发布:java deleteonexit 编辑:程序博客网 时间:2024/06/03 12:26

题目链接:

题目大意;给出的一系列的数字,可以看成一个双向队列,每次只能从队首或者队尾出队,第n个出队就拿这个数乘以n,最后将和加起来,求最大和

思路:区间dp,从小的区间推大的区间,即从最后一个出去的往前推。

一开始初始化边界,即最后一个出去,然后逐渐加大区间,判断这个区间的左右两个端点

推导公式为:

(dp[i][j]指的是区间i到j区间的数从最后开始出去的最大价值)

dp[i][j]=max(dp[i+1][j]+a[i]*(n-d),dp[i][j-1]+a[j]*(n-d));

#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>using namespace std;#define maxn 2100#define inf 0x3f3f3f3fint dp[maxn][maxn];int n;int a[maxn];int main(){while(~scanf("%d",&n)){for(int i=1;i<=n;i++)scanf("%d",&a[i]);memset(dp,0,sizeof dp);for(int i=1;i<=n;i++)dp[i][i]=a[i]*n;//边界 从后往前推for(int d=1;d<n;d++){for(int i=1,j;(j=i+d)<=n;i++){dp[i][j]=max(dp[i+1][j]+a[i]*(n-d),dp[i][j-1]+a[j]*(n-d));}}printf("%d\n",dp[1][n]);}    return 0;}