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

POJ3186 Treats for the Cows —— 区间DP

POJ 3186 Treats for the Cows (简单区间DP)

POJ 3186Treats for the Cows (区间DP)

POJ 3186Treats for the Cows(区间DP)

POJ - 3186 Treats for the Cows (区间DP)

poj 3186 Treats for the Cows (区间dp)