zoukankan      html  css  js  c++  java
  • hdu1693:eat trees(插头dp)

    题目大意:

    题目背景竟然是dota!屠夫打到大后期就没用了,,只能去吃树!

    给一个n*m的地图,有些格子是不可到达的,要把所有可到达的格子的树都吃完,并且要走回路,求方案数

    题解:

    这题大概是最简单的插头dp了。。

    比陈丹琦论文里的例题还要简单,因为允许有多个回路,所以不需要存储插头之间的连通性,直接二进制状压

    搞清楚插头和轮廓线的概念基本就可以做出来了

    这里有一些资料http://www.docin.com/p-741918386.html

    代码:

    #include <iostream>
    #include <stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<string>
    #include<ctype.h>
    using namespace std;
    #define MAXN 10000
    long long dp[13][13][1<<13];
    int g[13][13];
    int n,m;
    int main()
    {
        int t,cas=0;
        scanf("%d",&t);
        while(t--)
        {
            cas++;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    scanf("%d",g[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 u=1<<j;
                        int l=1<<(j-1);
                        if(g[i][j]==0)
                        {
                            if((!(k&u))&&(!(k&l)))
                                dp[i][j][k]=dp[i][j-1][k];
                            continue;
                        }
                        if((k&u)&&(k&l))
                        {
                            dp[i][j][k-u-l]+=dp[i][j-1][k];
                        }
                        if((k&u)&&(!(k&l)))
                        {
                            dp[i][j][k]+=dp[i][j-1][k];
                            dp[i][j][k-u+l]+=dp[i][j-1][k];
                        }
                        if((k&l)&&(!(k&u)))
                        {
                            dp[i][j][k]+=dp[i][j-1][k];
                            dp[i][j][k-l+u]+=dp[i][j-1][k];
                        }
                        if((!(k&u))&&(!(k&l)))
                        {
                            dp[i][j][k+u+l]+=dp[i][j-1][k];
                        }
                    }
                }
            }
            printf("Case %d: There are %I64d ways to eat the trees.
    ",cas,dp[n][m][0]);
        }
        return 0;
    }
  • 相关阅读:
    定时器
    WPF拖动总结
    将两个不同进程的窗口设置为父子关系
    Docker私有仓库管理
    Dockerfile创建zabbix监控体系
    Dockfile自动创建discuz论坛和可道云
    Docker的自动构建镜像
    Docker简介
    Mapreduce
    分布式文件系统与HDFS
  • 原文地址:https://www.cnblogs.com/oneshot/p/4126379.html
Copyright © 2011-2022 走看看