POJ - 3186 Treats for the Cows

Posted shiyu-coder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 3186 Treats for the Cows相关的知识,希望对你有一定的参考价值。

题目:

给你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的主要内容,如果未能解决你的问题,请参考以下文章