您的位置:首页 > 其它

POJ 3186 Treats for the Cows【区间DP+思维】

2018-02-12 12:12 453 查看
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);状态转移:dp[i][j]=max(dp[i+1][j]+a[i]∗L,dp[i][j−1]+a[j]∗L);

dp[i][j]:表示进队时[i,j]区间最大值;进队后的新序列是最优解而并非是原序列。dp[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]
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: