POJ2228 Naptime

http://poj.org/problem?id=2228

题意

环形DP

本来考虑把区间复制一遍,然后截取一段区间的方法,结果假掉了

实际上特判一下就行了

要么第一时刻不睡觉,直接\(DP\)

要么第一时刻睡觉,那么最后一时刻必须睡觉,再\(DP\)一次

\(Over\)了。

\(C++ Code:\)

#include<cstdio>
#include<iostream>
#define N 3835
#define INF 1000000009
using namespace std;
int dp[2][N][2];
int n,b,a[N];
int main()
{
    scanf("%d%d",&n,&b);
    for (int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for (int i=0;i<2;i++)
        for (int j=0;j<=b;j++)
            for (int k=0;k<2;k++)
                dp[i][j][k]=-INF;
    dp[0][0][0]=0;
    for (int i=1;i<=n;i++)
    {
        int now=i&1;
        int pre=now^1;
        for (int j=0;j<=b;j++)
            for (int k=0;k<2;k++)
                dp[now][j][k]=-INF;
        for (int j=0;j<=b;j++)
        {
            dp[now][j][0]=max(dp[pre][j][0],dp[pre][j][1]);
            if (j)
                dp[now][j][1]=max(dp[pre][j-1][0],dp[pre][j-1][1]+a[i]);
        }
    }
    int ans=max(dp[n&1][b][0],dp[n&1][b][1]);
    for (int i=0;i<2;i++)
        for (int j=0;j<=b;j++)
            for (int k=0;k<2;k++)
                dp[i][j][k]=-INF;
    dp[0][0][0]=0;
    dp[1][0][0]=0;
    dp[1][1][1]=a[1];
    for (int i=2;i<=n;i++)
    {
        int now=i&1;
        int pre=now^1;
        for (int j=0;j<=b;j++)
            for (int k=0;k<2;k++)
                dp[now][j][k]=-INF;
        for (int j=0;j<=b;j++)
        {
            dp[now][j][0]=max(dp[pre][j][0],dp[pre][j][1]);
            if (j)
                dp[now][j][1]=max(dp[pre][j-1][0],dp[pre][j-1][1]+a[i]);
        }
    }
    ans=max(ans,dp[n&1][b][1]);
    cout << ans << endl;
    return 0;
}
posted @ 2020-07-24 16:07  GK0328  阅读(75)  评论(0编辑  收藏  举报