标签:就是 pre main 新手 价值 假设 输出 NPU cow
题目:
给你n个数字v(1),v(2),...,v(n-1),v(n),每次你可以取出最左端的数字或者取出最右端的数字,一共取n次取完。假设你第i次取的数字是x,你可以获得i*x的价值。你需要规划取数顺序,使获得的总价值之和最大。Input第一行一个数字n(1<=n<=2000)。
下面n行每行一个数字v(i)。(1<=v(i)<=1000)Output输出一个数字,表示最大总价值和。Sample Input
5 1 3 1 5 2
Sample Output
43
Hint按照这种下标顺序取数: 1, 5, 2, 3, 4
取出的数按顺序为:1, 2, 3, 1, 5
最大总价值和:1x1 + 2x2 + 3x3 + 4x1 + 5x5 = 43.
分析:
作为dp新手,每道题都做的如此艰难……这道题是区间dp稍微改变了一点,不需要纠结拿走的最后一个数字在哪,
直接把每个数字作为最后一个数字的情况全部遍历一遍就行了,有点像数塔问题。
区别就是这里不是简单的两个数相加合并,而是一个区间吞并了左边或右边的一个数
代码:
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 5 int N[2002]={0}; 6 int dp[2002][2002]={0}; 7 8 int main(){ 9 int n; 10 cin >>n; 11 for(int i=1;i<=n;i++){ 12 cin >>N[i]; 13 } 14 //反向区间dp 15 for(int len=0;len<n;len++){ //区间长度 16 for(int j=1;j+len<=n;j++){ //区间起点 17 dp[j][j+len]=max(dp[j+1][j+len]+N[j]*(n-len),dp[j][j+len-1]+N[j+len]*(n-len)); 18 } 19 } 20 cout <<dp[1][n]<<endl; 21 system("pause"); 22 return 0; 23 }
POJ - 3186 Treats for the Cows
标签:就是 pre main 新手 价值 假设 输出 NPU cow
原文地址:https://www.cnblogs.com/shiyu-coder/p/13195519.html