首页 > 其他分享 >POJ 2228 Naptime 环形DP

POJ 2228 Naptime 环形DP

时间:2023-02-21 19:03:04浏览次数:36  
标签:cout 2228 int Naptime 间隔 ret POJ max dp

先不考虑环的情况
dp[i][j][0]:前i个时间间隔中,已经花费了j个间隔,取得的最大值,并且第i个间隔在休息
dp[i][j][1]:前i个时间间隔中,已经花费了j个间隔,取得的最大值,并且第i个间隔不休息

转态转移

dp[i&1][j][1] = max(dp[(i+1)&1][j][0],dp[(i+1)&1][j][1]);
dp[i&1][j][0] = max(dp[(i+1)&1][j-1][0] + a[i],dp[(i+1)&1][j-1][1]);

最后的结果 ans = max(dp[N][B][0],dp[N][B][1])

考虑成环
由于N值过大,将输入变成两倍接到后面的做法不可取,tle

我们先令dp[1][1][0] = a[1],即在上一天最后一个时间段一定在sleep
然后重新运行DP,这样除了最后一段时间和第一段时间,其他的时间段都是成环之后的正确值。
我们再来看第一段和最后一段
在最后一段sleep的情况下,第一段显然是正确的
这是我们取 ans = max(ans,dp[N][B][0]),即最后一段时间一定在睡觉即可。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <limits.h>

using namespace std;

#define debug(x) cout<<#x<<": "<<x<<endl;

int N,B;
int a[3831];
int dp[2][3031][2];

void disp(){
for(int i=0;i<=N;i++){
for(int j=0;j<=B;j++){
cout<<dp[i][j][0]<<" ";
cout<<dp[i][j][1]<<" ";
cout<<" ";
}
cout<<endl;
}

}
int main()
{

while( scanf("%d%d",&N,&B)!=EOF ){
memset(dp,0x80,sizeof(dp));
int ret = -1;
for(int i=1;i <= N;i++){
scanf("%d",&a[i]);
}
dp[1][0][1] = 0;
dp[1][1][0] = 0;

for( int i = 2;i <= N;i ++ ){
for(int j = 0;j <= B;j ++){
dp[i&1][j][1] = max(dp[(i+1)&1][j][0],dp[(i+1)&1][j][1]);
if(j){
dp[i&1][j][0] = max(dp[(i+1)&1][j-1][0] + a[i],dp[(i+1)&1][j-1][1]);
}
}
}

//debug(111)
ret = max(dp[N&1][B][0],dp[N&1][B][1]);


memset(dp,0x80,sizeof(dp));
dp[1][1][0] = a[1];
for(int i=2;i<=N;i++){
for(int j=0;j<=B;j++){
dp[i&1][j][1] = max(dp[(i+1)&1][j][0],dp[(i+1)&1][j][1]);
if(j){
dp[i&1][j][0] = max(dp[(i+1)&1][j-1][0]+a[i],dp[(i+1)&1][j-1][1]);
}
}
}
//disp();
//ret = max(ret,dp[N&1][B][1]);
ret = max(ret,dp[N&1][B][0]);

cout<<ret<<endl;
}
return 0;
}

POJ 2228 Naptime 环形DP_环形DP


标签:cout,2228,int,Naptime,间隔,ret,POJ,max,dp
From: https://blog.51cto.com/liyunhao/6077027

相关文章

  • [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)
    题目vjudgeURL:​​CountingDivisors(square)​​​Letbethenumberofpositivedivisorsof.Forexample,,and.LetGiven,find.InputFirstlinecontains......
  • POJ 3345 Bribing FIPA
      #include<iostream>#include<map>#include<algorithm>#include<cstring>usingnamespacestd;constintN=203,M=N;typedeflonglongll;intn......
  • poj 2230
    求一个无向图的欧拉回路,但要求每条边正反过一次 当作有向图,打标记只打一条边 #include<iostream>#include<algorithm>#include<cstring>#include<stack>usi......
  • POJ - 1664 放苹果
    把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1是同一种分法。Input第一行是测试数据的数目t(0<=t<=20)。以下每行均包......
  • 二分查找水题--疯牛(POJ 2456)
    DescriptionFarmerJohnhasbuiltanewlongbarn,withN(2<=N<=100,000)stalls.Thestallsarelocatedalongastraightlineatpositionsx1,...,xN(0<=x......
  • Poj 2503 map sscanf
    Poj2503mapsscanf题意字符串的映射,但它输入的方式很怪。首先每行输入两个单词,中间隔一个空格,到输入空行为止。然后每行输入一个单词,如果能存在映射的单词就输出对......
  • Pseudoprime numbers(POJ-3641 快速幂)
    快速幂:快速幂就是所求的幂次方过大,导致代码所用的时间超限。如:求2^3,3的二进制是11,(n&1)判断次方数的二进制是否为1,n>>1,向右进位1:代码:k=1,t=n;while(n){if(n&1)//......
  • Cash Machine (POJ 1276)(多重背包——二进制优化)
    链接:POJ-1276题意:给你一个最大金额m,现在有n种类型的纸票,这些纸票的个数各不相同,问能够用这些纸票再不超过m的前提下凑成最大的金额是多少?题解:写了01背包直接暴力,结......
  • Subsequence (POJ - 3061)(尺取思想)
    ProblemAsequenceofNpositiveintegers(10<N<100000),eachofthemlessthanorequal10000,andapositiveintegerS(S<100000000)aregiven.W......
  • Til the Cows Come Home ( POJ 2387) (简单最短路 Dijkstra)
    problemBessieisoutinthefieldandwantstogetbacktothebarntogetasmuchsleepaspossiblebeforeFarmerJohnwakesherforthemorningmilking.......