【HDU】【1693】Eat The Trees

插头DP

  插头dp模板题……

  这题比CDQ论文上的例题还要简单……因为不用区分左右插头(这题可以多回路,并不是一条哈密尔顿路)

  硬枚举当前位置的状态就好了>_<

  题解:http://blog.csdn.net/xymscau/article/details/6756351

 1 //HDU 1693
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define rep(i,n) for(int i=0;i<n;++i)
 8 #define F(i,j,n) for(int i=j;i<=n;++i)
 9 #define D(i,j,n) for(int i=j;i>=n;--i)
10 using namespace std;
11 int getint(){
12     int v=0,sign=1; char ch=getchar();
13     while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();}
14     while(isdigit(ch))  {v=v*10+ch-‘0‘; ch=getchar();}
15     return v*sign;
16 }
17 /*******************template********************/
18 const int N=13;
19 typedef long long LL;
20 int mp[N][N];
21 LL dp[N][N][1<<N];
22 int n,m;
23
24 void DP(){
25     memset(dp,0,sizeof (dp));
26     dp[0][m][0]=1;
27     F(i,1,n){//第i行
28 //        for(int j=0;j<(1<<m);j++)
29         rep(j,(1<<m))
30             dp[i][0][(j<<1)]=dp[i-1][m][j];
31         //换行(将上一行最后一格状态放到这一行第一格,方便转移……)
32
33         F(k,1,m)//第k个格子
34             rep(sta,1<<(m+1)){//枚举当前状态sta
35                 int y=1<<k,x=1<<(k-1);
36                 if(mp[i][k]){//如果当前格子无障碍
37                     if( (sta&x)!=0 && (sta&y)!=0 )//如果状态为(1,1)
38                         dp[i][k][sta]=dp[i][k-1][sta-x-y];//从(0,0)转移过来
39                     else if( (sta&x)==0 && (sta&y)==0 )//如果状态为(0,0)
40                         dp[i][k][sta]=dp[i][k-1][sta+x+y];//从(1,1)转移过来
41                     else //状态为(0,1)或(1,0)则从(1,0)&&(0,1)转过来
42                         dp[i][k][sta]=dp[i][k-1][sta^x^y]+dp[i][k-1][sta];
43                 }//如果当前格子有障碍
44                 else
45                     if( (sta&x)==0 && (sta&y)==0)//若当前状态为(0,0)
46                         dp[i][k][sta]=dp[i][k-1][sta];//则ans从前一格
47                     else
48                         dp[i][k][sta]=0;
49             }
50     }
51     printf("There are %lld ways to eat the trees.\n",dp[n][m][0]);
52 }
53 int main(){
54     int T=getint(),num=0;
55     while(T--){
56         num++;
57         n=getint();m=getint();
58         F(i,1,n)
59             F(j,1,m) mp[i][j]=getint();
60         printf("Case %d: ",num);
61         DP();
62     }
63     return 0;
64 }

(带注释)

时间: 2024-11-19 11:12:58

【HDU】【1693】Eat The Trees的相关文章

【HDU 4612 Warm up】BCC 树的直径

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4612 题意:一个包含n个节点m条边的无向连通图(无自环,可能有重边).求添加一条边后最少剩余的桥的数目. 思路:要想尽可能地消灭桥,那么添加的这条边一定是连通了最多的BCC. 所以首先进行双连通分量分解,并记录桥的数目:然后将同属一个BCC的点缩成一个,代之以block序号,以block序号为点将原图重构为一棵树. 最后求树的直径,桥的数目减去树的直径即为答案. 整体框架是学习了 http://w

HDU4841 圆桌问题 【HDU最烂题】

圆桌问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 295    Accepted Submission(s): 105 Problem Description 圆桌上围坐着2n个人.其中n个人是好人,另外n个人是坏人.如果从第一个人开始数数,数到第m个人,则立即处死该人:然后从被处死的人之后开始数数,再将数到的第m个人处死--依

【HDU 5818多校】Joint Stacks

用两个栈模拟,并保存每个点的时间戳.每次合并的时候记录合并时的时间戳mcnt和此时的topa和topb记做ta.tb. 每次pop的时候,如果栈的top的时间戳大于mcnt,则普通地pop,否则就在两个栈ta和tb下面找时间戳最大且还没pop掉的.然后用bj[时间戳]来标记已经pop了. #include <cstdio> #include <cstring> #define N 100005 using namespace std; struct node{ int id,v;

【HDU 5810多校】Balls and Boxes(打表/数学)

1.打表找规律,下面是打表程序: #include <iostream> #include <cstdio> #define ll long long #define N 100005 using namespace std; ll n,m,b[N],ans,num; ll sqr(ll x) { return x*x; } void dfs(ll r){ if(r==0){ num++; for(int i=1;i<=m;i++) ans+=sqr(b[i]); retur

【HDU刷题册】

LEVEL 级别描述 E 水题,完全无须任何数据结构/算法知识 D 思维题,无须数据结构/算法知识 C 特定数据结构/算法/数学知识 B 特定数据结构/算法/数学知识,加一些综合 A 综合性题目 已完成 ID LEVEL TAG Analysis Date 1000 E 水题 格式练习 - 2018-10-28 09:38:41 1001 E 水题 循环 - 2018-11-21 20:39:08 1002 D+ 水题 大数相加 格式练习 题解 2018-11-22 20:16:16 1003

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

【插头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

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

【HDU】1663 Eat the Trees

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693 给出一块$r*c$的地,其中有的土地上种上了树,有些没有种上树,只能在种上树的地上走,通过走若干个回路,来走遍所有种树的土地.问有多少种走法. 插头DP. 既然可以走多个回路,似乎就不需要考虑括号序列合并的问题了,直接状压表示每一个位置有没有插头. 我写的转出. 1.如果当前点都没有上插头和左插头,那么插头无法延续,新建一个回路. 2.如果当前点都有上插头和左插头,回路在此处闭合. 3.如果上