码迷,mamicode.com
首页 > 其他好文 > 详细

POJ - 3186 Treats for the Cows

时间:2020-06-26 18:00:32      阅读:42      评论:0      收藏:0      [点我收藏+]

标签:就是   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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!