Review For Exam

[2019 福建省赛]

一个很简单的状态压缩DP,结果集体走偏

如何解决连续几日的限制问题?这种东西普通的DP很难写

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1010;
ll dp[maxn][1050];
ll val[maxn];
bool vis[1050];
const ll inf =0x3f3f3f3f3f3f3f3f;
int main() {
    int n,k,a,b;
    scanf("%d%d%d%d",&n,&k,&a,&b);
    for(int i=1;i<=n;++i) scanf("%lld",&val[i]);
    int mx=(1<<k)-1;
    memset(dp,-0x3f3f3f3f,sizeof(dp));
    for(int j=0,tmp;j<=mx;++j){
        tmp=0;
        for(int i=0;i<k;++i){
            if((j>>i)&1){
               tmp++;
            }
        }
        if(tmp<=b&&tmp>=a) {
            vis[j]=1;
            dp[1][j]=0;
            for(int i=0;i<k;++i){
                if((j>>i)&1){
                   dp[1][j]+=val[k-i];
                }else{
                    dp[1][j]-=val[k-i];
                }
            }
        }
    }
    int tmp,tmpp,op;
    for(int i=2;i<=n-k+1;++i){
        for(int j=0;j<=mx;++j){
            if(vis[j]){
                tmp=j>>1;
                tmpp=tmp+(1<<(k-1));
                op=j%2;
                if(op){
                    if(vis[tmp])
                    dp[i][j]=max(dp[i-1][tmp]+val[i+k-1],dp[i][j]);
                    if(vis[tmpp])
                        dp[i][j]=max(dp[i-1][tmpp]+val[i+k-1],dp[i][j]);
                }else{
                    if(vis[tmp])
                        dp[i][j]=max(dp[i-1][tmp]-val[i+k-1],dp[i][j]);
                    if(vis[tmpp])
                        dp[i][j]=max(dp[i-1][tmpp]-val[i+k-1],dp[i][j]);
                }
            }
        }
    }
    ll ans=-inf;
    for(int j=0;j<=mx;++j){
        ans=max(dp[n-k+1][j],ans);
    }
    printf("%lld\n",ans);
    return 0;
}