POJ 3186.
Description
FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for giving vast amounts of milk. FJ sells one treat per day and wants to maximize the money he receives over a given period time.
The treats are interesting for many reasons:
The treats are numbered 1..N and stored sequentially in single file in a long box that is open at both ends. On any day, FJ can retrieve one treat from either end of his stash of treats.
Like fine wines and delicious cheeses, the treats improve with age and command greater prices.
The treats are not uniform: some are better and have higher intrinsic value. Treat i has value v(i) (1 <= v(i) <= 1000).
Cows pay more for treats that have aged longer: a cow will pay v(i)*a for a treat of age a.
Given the values v(i) of each of the treats lined up in order of the index i in their box, what is the greatest value FJ can receive for them if he orders their sale optimally?
The first treat is sold on day 1 and has age a=1. Each subsequent day increases the age by 1.
Input
Line 1: A single integer, N
Lines 2..N+1: Line i+1 contains the value of treat v(i)
Output
Line 1: The maximum revenue FJ can achieve by selling the treats
Sample Input
5
1
3
1
5
2
Sample Output
43
题意:给你一串数字,可以看成一个双向队列,每次只能从队首或者队尾出队,第n个出队就拿这个数乘以n,求最大和.
题
意
:
给
你
一
串
数
字
,
可
以
看
成
一
个
双
向
队
列
,
每
次
只
能
从
队
首
或
者
队
尾
出
队
,
第
n
个
出
队
就
拿
这
个
数
乘
以
n
,
求
最
大
和
.
分析:
分
析
:
贪心肯定不行,如果正面考虑的话,没有任何连续性,好像也没有什么逻辑关系。逆序进队,初始队列为空。
贪
心
肯
定
不
行
,
如
果
正
面
考
虑
的
话
,
没
有
任
何
连
续
性
,
好
像
也
没
有
什
么
逻
辑
关
系
。
逆
序
进
队
,
初
始
队
列
为
空
。
先进队的a[i]∗n。逆序考虑就有一定的连续性了,如果a[i]是第L个进队,那么第L−1个进队的就是a[i+1]或者a[i−1];
先
进
队
的
a
[
i
]
∗
n
。
逆
序
考
虑
就
有
一
定
的
连
续
性
了
,
如
果
a
[
i
]
是
第
L
个
进
队
,
那
么
第
L
−
1
个
进
队
的
就
是
a
[
i
+
1
]
或
者
a
[
i
−
1
]
;
状态转移:dp[i][j]=max(dp[i+1][j]+a[i]∗L,dp[i][j−1]+a[j]∗L);
状
态
转
移
:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
+
1
]
[
j
]
+
a
[
i
]
∗
L
,
d
p
[
i
]
[
j
−
1
]
+
a
[
j
]
∗
L
)
;
dp[i][j]:表示进队时[i,j]区间最大值;进队后的新序列是最优解而并非是原序列。
d
p
[
i
]
[
j
]
:
表
示
进
队
时
[
i
,
j
]
区
间
最
大
值
;
进
队
后
的
新
序
列
是
最
优
解
而
并
非
是
原
序
列
。
*反面考虑的题目遇到的不少了,注意这个点。。。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const int MAXN = 2e3 + 10;
int a[MAXN], dp[MAXN][MAXN];
int main() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for(int L = n; L >= 1; --L) { //逆序进队
for(int i = 1; i <= L; ++i) { //起点
int j = i + n - L; //终点
dp[i][j] = max(dp[i + 1][j] + a[i] * L, dp[i][j - 1] + a[j] * L);
}
}
printf("%d\n", dp[1][n]);
return 0;
}