首页 > 代码库 > 区间DP Treats for the Cows POJ - 3186
区间DP Treats for the Cows POJ - 3186
题意:给长度为n的序列,每次只能从首或尾取一个数,第i次取的数权值为(数值*i),求取完所有的数可以达到的最大权值。
网上都说是简单dp,自己想了很久都没想明白。。。
从后面推前面,由小区间推大区间。dp[i][j]代表要取的区间[i,j] ,区间长度为n的序列,从区间长度为1开始推,dp[i][i]=n*a[i]表示最后一个取走的数是i;
当区间长度为2时 dp[i][i+1]=max(dp[i][i]+a[i+1]*(n-1),dp[i+1][i+1]+a[i]*(n-1)) 表示从(最后取走的数是i,倒数第二取走的数是i+1),(最后取走的数是i+1,倒数第二取走的数是 i)中取最大值。
dp[i][j]=max(dp[i+1][j]+a[i]*(n-j+i),dp[i][j-1]+a[j]*(n-j+i));
想清楚后还是蛮简单的。。
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define maxn 2005 using namespace std; int a[maxn],dp[maxn][maxn]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i][i]=n*a[i]; } for(int l=2;l<=n;l++) { for(int i=1;i<=n-l+1;i++) { int j=i+l-1; dp[i][j]=max(dp[i+1][j]+a[i]*(n-l+1),dp[i][j-1]+a[j]*(n-l+1)); } } printf("%d\n",dp[1][n]); return 0; }
区间DP Treats for the Cows POJ - 3186
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。