BZOJ3771:Triple FFT+容斥原理
BZOJ3577:玩手机 最大流+二维ST表优化

BZOJ3628:[JLOI2014]天天酷跑 dp

shinbokuow posted @ Feb 04, 2015 10:48:36 AM in BZOJ with tags dp , 1164 阅读

思路:

绝对是逗逼题,今年四月份的时候我居然都不会做...果然是幼儿园水平无力啊...

枚举Maxh,以及Maxcombo(什么枚举?没错就是枚举)

用一个Hash表存一下状态,然后随便分层dp就过了.

具体的状态设计见代码.

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
 
int n,m,c1,c2;
 
int w[100010][21];
int Maxh,Maxn;
int res,ansh,ansn;
 
int f[2][21][21][6];
struct State{
    int y,h,t;
    State(){}
    State(int _y,int _h,int _t):y(_y),h(_h),t(_t){}
};
struct HashSet{
    int s[21][21][6],cnt;
    State sav[21*21*6];
    inline void reset(){cnt=0,memset(s,0xc0,sizeof s);}
    inline int Max(){
        int res=-1<<30;
        for(int j=1;j<=cnt;++j)res=max(res,s[sav[j].y][sav[j].h][sav[j].t]);
        return res;
    }
    inline void insert(State x,int w){
        if(s[x.y][x.h][x.t]==0xc0c0c0c0)s[x.y][x.h][x.t]=w,sav[++cnt]=x;
        else if(w>s[x.y][x.h][x.t])s[x.y][x.h][x.t]=w;
    }
}S[2];
inline void relax(int lab,int x,int y,int h,int t,int lastw){
    if(w[x][y]==-1)return;
    S[lab].insert(State(y,h,t),lastw+w[x][y]);
}
inline void Solve(){
    int now=0,last=1,ans=0xc0c0c0c0;
    S[now].reset(),S[now].insert(State(1,0,Maxn),0);
    register int i,j;
    State p;int w;
    for(i=1;i<=n;++i){
        swap(now,last),S[now].reset();
        for(j=1;j<=S[last].cnt;++j){
            p=S[last].sav[j],w=S[last].s[p.y][p.h][p.t];
            if(p.y==1){
                relax(now,i,1,0,Maxn,w);
                relax(now,i,2,Maxh-1,Maxn-1,w);
            }
            else if(p.h==0){
                if(p.t)relax(now,i,p.y+1,Maxh-1,p.t-1,w);
                relax(now,i,p.y-1,0,p.t,w);
            }
            else relax(now,i,p.y+1,p.h-1,p.t,w);
        }
    }
    ans=max(ans,S[now].Max()-(Maxn-1)*c2-(Maxh-1)*c1);
    if(ans>res)res=ans,ansn=Maxn,ansh=Maxh;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&c1,&c2);register int i,j;
    for(j=1;j<=m;++j)for(i=1;i<=n;++i)scanf("%d",&w[i][j]);
     
    res=0xc0c0c0c0;
    for(Maxn=1;Maxn<=5;++Maxn)
        for(Maxh=1;Maxh*Maxn<m;++Maxh)
            Solve();
     
    if(res==0xc0c0c0c0)puts("mission failed");else printf("%d %d %d\n",res,ansn,ansh);
     
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter