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; 
    }
    

      

  • 相关阅读:
    UVa532 Dungeon Master 三维迷宫
    6.4.2 走迷宫
    UVA 439 Knight Moves
    UVa784 Maze Exploration
    UVa657 The die is cast
    UVa572 Oil Deposits DFS求连通块
    UVa10562 Undraw the Trees
    UVa839 Not so Mobile
    327
    UVa699 The Falling Leaves
  • 原文地址:https://www.cnblogs.com/guangheli/p/13080766.html
Copyright © 2011-2022 走看看