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>
 3 using namespace std;
 4
 5 const int N=2222;
 6 int dp[N][N],value[N];
 7
 8 int main(){
 9     int n;
10     cin>>n;
11     for(int i=1;i<=n;i++) cin>>value[i];
12     for(int i=n;i>=1;i--){
13         for(int j=i;j<=n;j++){
14             dp[i][j]=max(dp[i+1][j]+value[i]*(n+i-j),dp[i][j-1]+value[j]*(n+i-j));
15         }
16     }
17     cout<<dp[1][n]<<endl;
18     return 0;
19 }
时间: 2024-10-14 01:12:16

POJ - 3186 Treats for the Cows (区间DP)的相关文章

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 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 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)

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

O - 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

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

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<vect

POJ 3042 Grazing on the Run (区间DP)

区间dp,~~~~ dp[i][j][0]表示i到j之间已经走过,并且现在在i点的staleness(可以理解为枯萎指数)最小值, dp[i][j][1]表示i到j之间已经走过,并且现在在j点的staleness最小值. 于是对于在i点,可能从i+1->i,也可能从j->i,即: 很重要的一点,在我们转移到i时,除了即将到达的i点,还有未到达的(n-(j-i+1))个点,即总共(n-(j-i))个点,它们的枯萎指数均在增加,so~ dp[i][j][0]=min(dp[i+1][j][0]+(

POJ 3186Treats for the Cows(区间DP)

题目链接:http://poj.org/problem?id=3186 题目大意:给出的一系列的数字,可以看成一个双向队列,每次只能从队首或者队尾出队,第n个出队就拿这个数乘以n,最后将和加起来,求最大和. 解题思路:有两种写法: ①这是我一开始想的,从外推到内,设立数组dp[i][j]表示剩下i~j时的最优解,则有状态转移方程: dp[i][j]=dp[i][j]=max(dp[i-1][j]+a[i-1]*(n-(j-i+1)),dp[i][j+1]+a[j+1]*(n-(j+1-i)))