zoukankan      html  css  js  c++  java
  • BZOJ5336 DP套DP

    https://www.lydsy.com/JudgeOnline/problem.php?id=5336

    萌新第一次写dp套dp.

    先不考虑有NOI的限制.

    考虑普通lcs是怎么做的.

    f[i][j]=max(f[i-1][j],f[i][j-1],(f[i-1][j-1]+1)*[S[i]==T[j]]).

    设f[i]表示对于原串,生出串做到第i的位置时,最长公共子序列长度.

    发现相邻的i-1~i只会f值最多+1,于是可以对这个状态进行差分后,状压存储.

    预处理出在状态S后添加字符w[i],所得到的新的f[].

    设dp[i][S][len]表示dp到第i位,f的差分后状态位S,匹配NOI字符串的长度为len.

    添加字符w有

    dp[i][trans[S][w]][mp[len][w]]+=dp[i-1][S][len].

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define rep(i,s,t) for(register int i=s;i<=t;++i)
    #define _rep(i,s,t) for(register int i=s;i>=t;--i)
    #define Rep(i,s,t) for(register int i=s;i<t;++i)
    #define go(x) for(register int e=las[x];e;e=nxt[e])
    #define re register
    #define fi first
    #define se second
    #define mp(x,y) make_pair(x,y)
    #define pb push_back
    #define pii pair<int,int>
    #define gi(x) read(x)
    #define gii(x,y) read(x),read(y)
    #define giii(x,y,z) read(x),read(y),read(z)
    #define ms(f,x) memset(f,x,sizeof f)
    namespace IO{
        #define gc getchar()
        #define pc(x) putchar(x)
        template<typename T>inline void read(T &x){
            x=0;int f=1;char ch=gc;while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gc;}
            while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=gc;x*=f;return;
        }
        template<typename T>inline void write(T x=0){
            T wr[51];wr[0]=0;if(x<0)pc('-'),x=-x;if(!x)pc(48);
            while(x)wr[++wr[0]]=x%10,x/=10;while(wr[0])pc(48+wr[wr[0]--]);return;
        }
    }
    using IO::read;
    using IO::write;
    typedef long long ll;
    typedef double db;
    using namespace std;
    const int mod=1e9+7;
    char w[]={'N','O','I'};
    char ch[20];
    int n,m,S;
    int f[2][1<<15][3],mp[3][3],ans[1011];
    int g[20],h[20],trans[1<<15][3],sz[1<<15];
    inline void inc(int &x,int y){
        x+=y;
        if(x>=mod)x-=mod;
    }
    inline int zip(int *h){
        re int s=0;
        rep(i,1,n)
            s|=((h[i]-h[i-1])<<(i-1));
        return s;
    }
    inline void unzip(int *h,int s){
        rep(i,1,n)
            h[i]=h[i-1]+(s&1),s>>=1;
    }
    inline void init(){
        rep(i,1,S)sz[i]=sz[i>>1]+(i&1);
        rep(k,0,2)rep(s,0,S){
            unzip(g,s),ms(h,0);
            rep(i,1,n){
                h[i]=max(h[i-1],g[i]);
                if(w[k]==ch[i])
                    h[i]=max(h[i],g[i-1]+1);
            }
            trans[s][k]=zip(h);
        }
    }
    int main(){
        gii(m,n),scanf("%s",ch+1),S=(1<<n)-1,init();
        mp[0][0]=mp[1][0]=mp[2][0]=f[0][0][0]=1,mp[1][1]=2;
        rep(i,1,m){
            int p=i&1,q=p^1;
            ms(f[p],0);
            rep(s,0,S)rep(j,0,2)rep(k,0,2){
                if(k==2&&j==2)continue;
                re int y=trans[s][k];
                inc(f[p][y][mp[j][k]],f[q][s][j]);  
            }
        }
        rep(s,0,S)rep(j,0,2)
            inc(ans[sz[s]],f[m&1][s][j]);
        rep(i,0,n)
            printf("%d
    ",ans[i]);
        return 0;
    }
    
    BZOJ5336
  • 相关阅读:
    Log4net.config
    ASCII 转换帮助类
    维吉尼亚加密与解密
    nginx配置说明
    验证码
    css 设置下拉菜单
    输出一张自定义文字的图片
    mvc 自定义分页控件
    【模块化】export与export default在一个文件里共存,引入时需注意的地方
    【uniapp】兼容刘海屏底部安全区
  • 原文地址:https://www.cnblogs.com/Stump/p/9069293.html
Copyright © 2011-2022 走看看