zoukankan      html  css  js  c++  java
  • BZOJ5336: [TJOI2018]party

    BZOJ5336: [TJOI2018]party

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

    分析:

    • 好题。
    • 正常的思路是设(f[i][j][0/1/2])表示前(i)个位置,与奖章串的(lcs)状态为(j),匹配到(NOI)的第几位,然后转移。
    • 那么问题是这个(lcs)的状态如何存储,打个表发现这个状态数很少,实际上也是这样的,因为在匹配(lcs)的过程中,相邻两位(dp)值最多差(1),状态数(2^k)
    • 然后就做完了,预处理出来每个状态能转移到的状态即可。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    #define N 1050
    #define mod 1000000007
    char w[N];
    int n,K;
    typedef long long ll;
    int tr[1<<15][3],sf[N],sg[N],cnt[1<<15];
    ll f[2][1<<15][3],ans[N];
    inline void upd(ll &x,ll y) {
        x=x+y; if(x>=mod) x-=mod;
    }
    int main() {
        scanf("%d%d%s",&n,&K,w+1);
        int i,mask=(1<<K)-1,s;
        for(s=0;s<=mask;s++) {
            for(i=1;i<=K;i++) {
                sf[i]=sf[i-1]+((s>>(i-1))&1);
            }
            for(i=1;i<=K;i++) {
                if(w[i]=='N') sg[i]=sf[i-1]+1;
                else sg[i]=max(sg[i-1],sf[i]);
                tr[s][0]|=(sg[i]-sg[i-1])*(1<<(i-1));
            }
            for(i=1;i<=K;i++) {
                if(w[i]=='O') sg[i]=sf[i-1]+1;
                else sg[i]=max(sg[i-1],sf[i]);
                tr[s][1]|=(sg[i]-sg[i-1])*(1<<(i-1));
            }
            for(i=1;i<=K;i++) {
                if(w[i]=='I') sg[i]=sf[i-1]+1;
                else sg[i]=max(sg[i-1],sf[i]);
                tr[s][2]|=(sg[i]-sg[i-1])*(1<<(i-1));
            }
        }
        f[0][0][0]=1;
        for(i=0;i<n;i++) {
            int i0=i&1,i1=(i+1)&1;
            for(s=0;s<=mask;s++) {
                //O/I->N
                upd(f[i1][tr[s][0]][1],f[i0][s][0]);
                //O/I->O
                upd(f[i1][tr[s][1]][0],f[i0][s][0]);
                //O/I->I
                upd(f[i1][tr[s][2]][0],f[i0][s][0]);
                //N->N
                upd(f[i1][tr[s][0]][1],f[i0][s][1]);
                //N->O
                upd(f[i1][tr[s][1]][2],f[i0][s][1]);
                //N->I
                upd(f[i1][tr[s][2]][0],f[i0][s][1]);
                //NO->N
                upd(f[i1][tr[s][0]][1],f[i0][s][2]);
                //NO->O
                upd(f[i1][tr[s][1]][0],f[i0][s][2]);
            }
            memset(f[i0],0,sizeof(f[i0]));
        }
        for(i=0;i<=mask;i++) cnt[i]=cnt[i>>1]+(i&1);
        for(s=0;s<=mask;s++) for(i=0;i<3;i++) upd(ans[cnt[s]],f[n&1][s][i]);
        for(i=0;i<=K;i++) printf("%lld
    ",ans[i]);
    }
    
  • 相关阅读:
    用jQuery实现的简单柱状统计图
    转:Mac下配置eclipse的pydev
    准备做些东西
    UIImageJPEGRepresentation 和 UIImagePNGRepresentation
    UITableView,UITableViewCell,UIPickerView,UISearchBar
    UITableViewCell的显示格式
    js 数据类型检测
    data-xxx 属性的作用是什么
    TCP连接篇
    DNS篇
  • 原文地址:https://www.cnblogs.com/suika/p/10229852.html
Copyright © 2011-2022 走看看