POJ 3186 Treats for the Cows 一个简单DP

DP[i][j]表示现在开头是i物品,结尾是j物品的最大值,最后扫一遍dp[1][1]-dp[n][n]就可得到答案了

稍微想一下,就可以,

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int v[2005];
int dp[2005][2005];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
      scanf("%d",&v[i]);
    memset(dp,0,sizeof(dp));
    for(int k=n-1;k>=1;--k)
    {
        for(int i=1;i+k-1<=n;++i)
        {
            if(i>1)
            dp[i][i+k-1]=max(dp[i][i+k-1],dp[i-1][i+k-1]+v[i-1]*(n-k));
            if(i+k-1<n)
            dp[i][i+k-1]=max(dp[i][i+k-1],dp[i][i+k]+v[i+k]*(n-k));
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++)
       ans=max(ans,dp[i][i]+v[i]*n);
    printf("%d\n",ans);
    return 0;
}

时间: 2024-08-03 21:49:35

POJ 3186 Treats for the Cows 一个简单DP的相关文章

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

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

poj 3186 Treats for the Cows(区间dp)

Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4375   Accepted: 2226 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 da

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

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

poj 3186 Treats for the Cows dp

#include <cstdio> #include <algorithm> using namespace std; #define maxn 2100 int dp[maxn][maxn]; int val[maxn]; int n; int main() { while(scanf("%d",&n)!=EOF) { int i,j; for(i=1;i<=n;i++) { scanf("%d",&val[i]);

POJ 3189 Treats for the Cows(两种DP方法解决)

Treats for the Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4264   Accepted: 2155 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 da

POJ 3186 Treats for the Cows

一开始想到的是,用一个标志位记录取第i个数的时间,但后来发现这个方法不行,可能性太多,没办法推 然后就看了解题报告的思路,说是用区间dp,状态是设出来了,但受固有思维影响,老想着怎么顺着推. 最后实在想不出了,看了代码,才发现要逆着推,从结束状态开始推起,这样公式就出来了 为了保证每一层循环要用到的值都已经被计算出来了,按区间长度进行枚举 纪念第一个区间dp吧 /* dp[i][j]:剩下第i个至第j个物品时,取掉剩下的所有物品能获得的最大值 dp[i][j]=max(dp[i+1][j]+v[

poj 3186 Treats for the Cows (区间dp)

题意:给你一个序列,每次只能从头或为取数,然后乘以这是第几个数,最后加和,是加和最大 思路:假设长度最开始是1,然后依次枚举长度,以及起点,dp[i][j]是又里面的两端点扩出来的(ps:代码不是这么写的) 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=2007; int a[maxn],dp[maxn][maxn]; i

poj 2193 Lenny&#39;s Lucky Lotto Lists 简单dp

//poj 2193 //sep9 #include <iostream> using namespace std; typedef __int64 INT; INT dp[16][2048]; int n,m; int main() { int cases,t=0; scanf("%d",&cases); while(cases--){ scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp));

【POJ - 3186】Treats for the Cows (区间dp)

Treats for the Cows 先搬中文 Descriptions: 给你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 In