• Eat the Trees(hdu 1693)


    题意:在n*m的矩阵中,有些格子有树,没有树的格子不能到达,找一条或多条回路,吃完所有的树,求有多少中方法。

    第一道真正意义上的插头DP,可参考陈丹琦的《基于连通性状态压缩的动态规划问题》,虽然我看了一遍,但只是了解了个大概,主要还是看别人的代码,自己画图理解。

    插头和轮廓线的定义就不说了,在PPT中很好理解。

    先说一下转移的方式,如下图(p和q是当前枚举到的格子所面临的需要更新插头的地方):

    通过在纸上画图,可以得出这么几个结论:

    前一个状态的q和p都有插头的话,后一个状态的q和p都不能有插头。(因为一个显然格子只能有两个插头)

    前一个状态的q和p都没有插头的话,后一个状态的q和p都必须有插头。(因为每个格子必须经过)

    前一个状态的q和p任何一个有插头,后一个状态的q和p中只有一个有插头。

    得到这几个结论之后,就可以方便地转移了。

    最后在代码中有一点要注意的是,上一行的最后一列的状态可以转移到下一行第0列的状态,原因如下图:

    代码参考于:http://www.cnblogs.com/zhuangli/archive/2008/09/04/1283753.html

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 12
    using namespace std;
    int map[N][N],n,m;
    long long dp[N][N][1<<N];
    int main(){
        int T,cas=0;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    scanf("%d",&map[i][j]);
            memset(dp,0,sizeof(dp));
            dp[0][m][0]=1;
            for(int i=1;i<=n;i++){
                for(int j=0;j<(1<<m);j++)
                    dp[i][0][j<<1]=dp[i-1][m][j];
                for(int j=1;j<=m;j++){
                    for(int k=0;k<(1<<m<<1);k++){
                        int p=1<<j;
                        int q=p>>1;
                        bool x=k&p;
                        bool y=k&q;
                        if(map[i][j]){
                            dp[i][j][k]+=dp[i][j-1][k^p^q];
                            if(x!=y)
                                dp[i][j][k]+=dp[i][j-1][k];
                        }
                        else {
                            if(x==0&&y==0)
                                dp[i][j][k]=dp[i][j-1][k];
                            else
                                dp[i][j][k]=0;
                        }
                    }
                }
            }
            printf("Case %d: There are %I64d ways to eat the trees.
    ",++cas,dp[n][m][0]);
        }
        return 0;
    }
  • 相关阅读:
    质数
    解决Winform中ListView.TopItem设置的问题
    证书格式简介及不同格式之间的转换方式
    Postgresql如何清理pg_xlog
    VirtualBox 4.2 released !
    ImportError: No module named qtdemo_rc
    C#使用RSA证书文件加密和解密示例
    VIM自动关闭预览提示窗口
    VMware和VirtualBox中的网络适配器类型及虚拟网络性能优化
    正则表达式Java
  • 原文地址:https://www.cnblogs.com/harden/p/6560663.html
Copyright © 2020-2023  润新知