HDU - 1693 Eat the Trees(多回路插头DP)

题目大意:要求你将所有非障碍格子都走一遍,形成回路(可以多回路),问有多少种方法

解题思路:

参考基于连通性状态压缩的动态规划问题 - 陈丹琦

以下为代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 12
#define S (1 << 12)
int n, m;
long long dp[N][N][S];
int cas = 1;

void solve() {
    scanf("%d%d", &n, &m);
    memset(dp, 0, sizeof(dp));

    int num;
    dp[0][0][0] = 1;
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < m; j++) {
            scanf("%d", &num);
            for(int k = 0; k < (1 << (m + 1)); k++) {
                int left = k & (1 << m);
                int up = k & (1 << j);
                int l = (1 << m);
                int u = (1 << j);
                //如果是障碍
                if(num == 0) {
                    if(!left && !up)
                        dp[i][j + 1][k] += dp[i][j][k];
                    continue;
                }
                //如果有左边那一个有右插头,上面那一个有下插头,那么当前格子只能是L的镜像了,也就是左上型
                if(left && up) {
                    dp[i][j + 1][k - l - u] += dp[i][j][k];
                }//如果只有左边那个有左插头,上面那个没有下插头,那么当前的可能有右插头,或者左下型插头
                else if(left) {
                    dp[i][j + 1][k] += dp[i][j][k];
                    dp[i][j + 1][k - l + u] += dp[i][j][k];
                }//如果只有上面那个有下插头,左边那个没有右插头,那么当前的可能有下插头,或者上右型插头
                else if(up) {//
                    dp[i][j + 1][k] += dp[i][j][k];
                    dp[i][j + 1][k - u + l] += dp[i][j][k];
                }//如果上面没有下插头,左边没有右插头,那么只能是下右型插头了
                else {
                    dp[i][j + 1][k + l + u] += dp[i][j][k];
                }
            }
        }
        for(int j = 0; j < (1 << m); j++)
            dp[i + 1][0][j] = dp[i][m][j];
    }
    printf("Case %d: There are %I64d ways to eat the trees.\n", cas++, dp[n][0][0]);
}

int main() {
    int test;
    scanf("%d", &test);
    while(test--) {
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-29 06:30:49

HDU - 1693 Eat the Trees(多回路插头DP)的相关文章

hdu 1693 Eat the Trees (插头dp入门)

Eat the Trees Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 1225 Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudg

HDU 1693 Eat the Trees 插头DP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:给出一块r*c的地,(r,c<=11),其中有的土地上种上了树,有些没有种上树,只能在种上树的地上走,通过走若干个回路,来走遍所有种树的土地.问有多少种走法. 思路:无论如何还是要先提供一个链接:http://wenku.baidu.com/view/4fe4ac659b6648d7c1c74633.html,是国家队论文,里面对于要提及的概念讲解的十分清楚. dp的过程是从左上角的点到右下

【插头DP】HDU 1693 Eat the Trees

通道:http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:多回路路径方案数,无障碍. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 10007; 1

HDU 1693 Eat the Trees (插头DP)

题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 以一个非障碍格子为单位进行DP转移,所以可以用滚动数组.只需要保存m+1个插头的状态,其中有一个是右插头,其他都是下插头,若有插头的存在,该位为1,否则为0,初始时都是0. 需要考虑的是,(1)如果两个边缘都是插头,那么必须接上它们:(2)如果仅有一边是插头,则延续插头,可以有两个延续的方向(下和右):(3)如果都没有插头,那么必须另开两个新

HDU 1693 Eat the Trees

Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a strong hero in the first period of the game. When the game goes to end however, Pudge is not a strong hero any more.So Pudge’s teammates give him a n

[Hdu 1693] Eat the Trees 轮廓线DP

题意 n * m 的矩形, 有坏点, 求划分成若干个回路的方案数. n, m <= 11 . 实现 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 #define LL long long 7 inlin

【HDU】1693 Eat the Trees

http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放.(n,m<=11) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; struct H { static const int M=1000007;

HDU 4113 Construct the Great Wall(插头dp)

好久没做插头dp的样子,一开始以为这题是插头,状压,插头,状压,插头,状压,插头,状压,无限对又错. 昨天看到的这题. 百度之后发现没有人发题解,hust也没,hdu也没discuss...在acm-icpc信息站发现难得的一篇题解.不过看到是插头二字之后,代码由于风格太不一样就没看了,自己想了好久,想通了.然后就等到今天才码.... 如果把点看成网格,那就可以实现,没有公共点公共边等限定条件,也显然是插头dp的最短单回路的模型.这是本题的一个难点(当时想到这样是因为,题目要求计算最短周长,显然

状态压缩插头DP

HDU 1693   Eat the Trees http://www.cnblogs.com/zhuangli/archive/2008/09/04/1283753.html http://blog.csdn.net/xymscau/article/details/6756351 题意:在N*M(1<=N, M<=11)的矩阵中,有些格子有树,没有树的格子不能到达,找一条或多条回路,吃完所有的树,求有多少种方法. 分析:轮廓线表示当前插头的状态,这题中状态中1表示有插头,0表示无插头.如果是