M_sea

SP283 NAPTIME - Naptime
题目描述传送门算法考虑线性DP。设$f[i][j][0]$表示$i$小时休息了$j$小时,并且第$i$小时不在休息...
扫描右侧二维码阅读全文
31
2018/08

SP283 NAPTIME - Naptime

题目描述

传送门

算法

考虑线性DP。

设$f[i][j][0]$表示$i$小时休息了$j$小时,并且第$i$小时不在休息的最大值,$f[i][j][1]$表示$i$小时休息了$j$小时,并且第$i$小时在休息的最大值。

显然有:

$$f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1])$$

$$f[i][j][1]=max(f[i-1][j-1][1]+a[i],f[i-1][j-1][0])$$

边界为$f[1][0][0]=f[1][1][1]=0$,答案为$max(f[n][b][0],f[n][b][1])$。

可惜,这样的做法会WA,原因是第一天的最后一个小时和第二天的第一个小时是连着的。

也就是说,上面的DP少了第一个小时获得了$a[1]$点体力的情况。

那么令边界为$f[1][1][1]=a[1]$,再DP一次即可。此时答案为$f[n][b][1]$。

注意,$f$数组一开始要初始化成-INF。(我之前因为初始化成-1导致样例没过)

代码

#include <bits/stdc++.h>
#define re register
using namespace std;

inline int max_(int a,int b) { if (a>b) return a; else return b; }
inline int min_(int a,int b) { if (a<b) return a; else return b; }
inline int read() {
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=(X<<3)+(X<<1)+c-'0',c=getchar();
    return X*w;
}

int n,b,ans=-1;
int a[4010];
int f[2][4010][2];

int main() {
    int T=read();
    while (T--) {
        memset(f,128,sizeof(f)); ans=-1;
        
        n=read(),b=read();
        for (re int i=1;i<=n;i++) a[i]=read();
        
        f[1][0][0]=f[1][1][1]=0;
        for (re int i=2;i<=n;i++) {
            int now=i&1,pre=now^1;
            for (re int j=0;j<=min_(i,b);j++) {
                f[now][j][0]=max_(f[pre][j][0],f[pre][j][1]);
                if (j) f[now][j][1]=max_(f[pre][j-1][1]+a[i],f[pre][j-1][0]);
            }
        }
        ans=max_(f[n&1][b][0],f[n&1][b][1]);
        
        memset(f,128,sizeof(f)); f[1][1][1]=a[1];
        for (re int i=2;i<=n;i++) {
            int now=i&1,pre=now^1;
            for (re int j=0;j<=min_(i,b);j++) {
                f[now][j][0]=max_(f[pre][j][0],f[pre][j][1]);
                if (j) f[now][j][1]=max_(f[pre][j-1][1]+a[i],f[pre][j-1][0]);
            }
        }
        ans=max_(ans,f[n&1][b][1]);
        printf("%d\n",ans);
    }
    return 0;
}
最后修改:2018 年 11 月 09 日 05 : 23 PM

发表评论