zoukankan      html  css  js  c++  java
  • 51nod1033

    骨牌覆盖,一开始写了插头DP。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring> 
    #define pp 1000000007
    using namespace std;
    long long dp[3][6][65];
    int n,m;
    int main()
    {
        scanf("%d %d",&n,&m);
        dp[0][m][0]=1;
        for(int i=1;i<=n;i++)
        {
            memset(dp[1],0,sizeof(dp[1]));
            for(int sta=0;sta<(1<<m);sta++)
            {
                dp[1][0][sta<<1]=dp[0][m][sta];
            }
            for(int j=1;j<=m;j++)
                for(int sta=0;sta<(1<<(m+1));sta++)
                {
                    int x=1<<(j-1);
                    int y=1<<j;
                    if((sta&x)==0&&(sta&y)==0)
                    dp[1][j][sta]=(dp[1][j-1][sta+x]+dp[1][j-1][sta+y])%pp;
                    if((sta&x)==0&&(sta&y)!=0)
                    dp[1][j][sta]=dp[1][j-1][sta-y];
                    if((sta&x)!=0&&(sta&y)==0)
                    dp[1][j][sta]=dp[1][j-1][sta-x];
                    //cout<<i<<' '<<j<<' '<<sta<<' '<<dp[i][j][sta]<<endl;
                }
            for(int j=1;j<=m;j++)    
                for(int sta=0;sta<(1<<(m+1));sta++)
                {
                    dp[0][j][sta]=dp[1][j][sta];
                }        
        }
        cout<<dp[1][m][0]<<endl;
     } 

    果断T掉,后来知道动态规划的原理就是把状态看成点,转移看成边,就是一个拓扑图。而这道题它的拓扑图结构比较清晰,要求的方案数可以用矩阵乘法来做,但是插头DP的状态与行列的值有关,好像不能这么搞。要用状压系列的(晕~~)。

    代码转自http://blog.csdn.net/naipp/article/details/52815127

    #include<bits/stdc++.h>
    using namespace std;
    #define mod 1000000007
    #define PI acos(-1.0)
    #define INF 0x3f3f3f3f
    typedef long long LL;
    typedef unsigned long long ULL;
    
    
    typedef vector<LL> vec;
    typedef vector<vec> mat;
    
    // A*B
    mat mul(mat& A, mat& B)
    {
        mat C(A.size(), vec(B[0].size()));
        for(int i = 0; i < (int)A.size(); ++i)
            for(int j = 0; j < (int)B[0].size(); ++j)
                for(int k = 0; k < (int)B.size(); ++k)
                    C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % mod;
        return C;
    }
    
    // A^n
    mat pow(mat A, int n)
    {
        mat B(A.size(), vec(A.size()));
        for(int i = 0; i < (int)A.size(); ++i) B[i][i] = 1;
        while(n)
        {
            if(n & 1) B = mul(B, A);
            A = mul(A, A);
            n >>= 1;
        }
        return B;
    }
    int n,m;
    LL dp[1<<5][1<<5];
    void dfs(int c,int pre,int now){
        if(c>n)return ;
        if(c==n){
            dp[pre][now]++;
            return ;
        }
        dfs(c+1,pre<<1,now<<1|1);
        dfs(c+1,pre<<1|1,now<<1);
        dfs(c+2,pre<<2,now<<2);
    }
    
    
    int main()
    {
            cin>>m>>n;
            mat a(1<<n,vec(1<<n));
            dfs(0,0,0);
            for(int i=0;i<(1<<n);i++){
                for(int j=0;j<(1<<n);j++){
                    a[i][j]=dp[i][j];
                    //cout<<a[i][j];
                }
                //cout<<endl;
            }
            a=pow(a,m+1);
            printf("%lld
    ",a[0][(1<<n)-1]);
    }
  • 相关阅读:
    微软外服 AlI In One
    js 循环多次和循环一次的时间的性能对比 All In One
    vue inject All In One
    Excel 表格数据倒置 All In One
    SVG tickets All In One
    OH MY ZSH All In One
    js array for loop performance compare All In One
    mac terminal show You have new mail All In one
    新闻视频 26 制作母版页
    转自牛腩 母版页和相对路径
  • 原文地址:https://www.cnblogs.com/dancer16/p/7338548.html
Copyright © 2011-2022 走看看