zoukankan      html  css  js  c++  java
  • BZOJ4321: queue2 dp

    按照套路,考虑将数字从小到大插入到序列中.

    令 $f[i][j]$ 表示将 $1$ ~ $i$ 插入到序列中,形成了 $j$ 对不合法的方案数.

    然后考虑将 $i+1$ 插入时的情况:

    1. 插入到不合法的空位中,消掉一个不合法.
    2. 插入到合法的空位中
    3. 插入到 $i$ 旁边,形成一个不合法.
    4. 插入到 $i$ 与 $i-1$ 的空位中,消掉一个不合法,又新形成一个不合法.

    我们发现,用 $f$ 不能很好地维护以上 4 中情况,所以引入 $g[i][j]$ 表示 $i$ 与 $i-1$ 相邻,并把 $f$ 的定义改成强制 $i$ 与 $i-1$ 不相邻即可.

    细节什么的要提前想清楚,最好多验算几遍,可以减少调试时间.  

    code:  

    #include <bits/stdc++.h>   
    #define ll long long 
    #define mod 7777777
    #define N 1009   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std; 
    int f[N][N],g[N][N],n;  
    int main() 
    { 
        // setIO("input");                    
        f[1][0]=1,g[1][0]=0,g[2][1]=2;   
        scanf("%d",&n);   
        for(int i=3;i<=n;++i) 
        {
            for(int j=0;j<i;++j)   
            {    
                f[i][j]=(ll)((ll)f[i-1][j+1]*(j+1)%mod+(ll)g[i-1][j+1]*j%mod)%mod;        
                g[i][j]=(ll)(g[i-1][j]+g[i-1][j-1])%mod;  
                if(j) (g[i][j]+=(ll)2*f[i-1][j-1]%mod)%=mod;    
                if(i-j-2>0) (f[i][j]+=(ll)f[i-1][j]*(i-j-2)%mod)%=mod;    
                if(i-j-1>0) (f[i][j]+=(ll)g[i-1][j]*(i-j-1)%mod)%=mod;      
            }
        } 
        printf("%d
    ",f[n][0]);   
        return 0; 
    }
    

      

  • 相关阅读:
    《人月神话》读后感
    软件工程心得体会(十一)
    Arch + Win10 EFI 引导重装记录
    BurpSuite 的使用
    Wireshark 的使用
    Android 中的反调试技术
    IDA 对 so 的动态调试
    Smail 中的一些点
    IDA 对 SO 的逆向
    动态调试smali代码
  • 原文地址:https://www.cnblogs.com/guangheli/p/13080766.html
Copyright © 2011-2022 走看看