您的位置:首页 > 其它

【dp】POJ - 3186 Treats for the Cows

2017-08-14 08:53 344 查看
Problem Description

给你一个n,接下来有n个数,你可以每次从最前面或者最后面取出一个数data,得到的价值就是data * (第几个取出这个数)。让你求出取完所有数得到的最大价值。

思路:

正常想法会想到贪心,每次取出最小的(这样会错)。所以我们选择用dp, dp[i][j],i表示左边取了i个,j边上右边取了j个。状态转移方程就是

dp[i][j] = max(dp[i - 1][j] + a[i] * (i + j), dp[i][j - 1] + a[n - j + 1]*(i + j));

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[2005], dp[2005][2005];
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
int ans = 0;
for(int i = 0; i <= n; i++)
{
for(int j = 0; j + i <= n; j++)
{
if(!i && !j)//没取
dp[i][j] = 0;
else if(!i)//只取右边
dp[i][j] = dp[i][j - 1] + a[n - j + 1] * (i + j);
else if(!j)//只取左边
dp[i][j] = dp[i - 1][j] + a[i] * (i + j);
else
dp[i][j] = max(dp[i - 1][j] + a[i] * (i + j), dp[i][j - 1] + a[n - j + 1]*(i + j));
ans = max(ans, dp[i][j]);//求最大
}
}
printf("%d\n", ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: