【HDU】1663 Eat the Trees

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693



给出一块$r*c$的地,其中有的土地上种上了树,有些没有种上树,只能在种上树的地上走,通过走若干个回路,来走遍所有种树的土地。问有多少种走法。



插头DP。

  既然可以走多个回路,似乎就不需要考虑括号序列合并的问题了,直接状压表示每一个位置有没有插头。

  我写的转出。

  1.如果当前点都没有上插头和左插头,那么插头无法延续,新建一个回路。

  2.如果当前点都有上插头和左插头,回路在此处闭合。

  3.如果上插头和左插头都只有一个,那么每一种状态有两种可以延续的方案。


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 13
10 #define llg long long
11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
12 llg n,m,g[maxn][maxn];
13 llg f[maxn][maxn][1<<(maxn+1)],T,tot;
14 void dp()
15 {
16     memset(f,0,sizeof(f));
17     tot=(1<<(m+1))-1;
18     f[0][m][0]=1;
19     for (llg i=1;i<=n;i++)
20     {
21         for (llg k=0;k<=tot;k++) f[i][0][k<<1]=f[i-1][m][k];
22         for (llg j=0;j<m;j++)
23         {
24             llg le=(1<<(j)),up=(1<<(j+1));//分别表示上左插头所在状态中的位置
25             for (llg k=0;k<=tot;k++)
26             {
27                 if (!g[i][j+1]) {if (!(k&le) && !(k&up)) f[i][j+1][k]=f[i][j][k]; continue;}
28                 if (!(k&le) && !(k&up)) {f[i][j+1][k+le+up]+=f[i][j][k]; continue;}
29                 if ((k&le) && (k&up)) {f[i][j+1][k-le-up]+=f[i][j][k]; continue;}
30                 if (k&le) {f[i][j+1][k-le+up]+=f[i][j][k]; f[i][j+1][k]+=f[i][j][k];}
31                 else {f[i][j+1][k-up+le]+=f[i][j][k]; f[i][j+1][k]+=f[i][j][k];}
32             }
33         }
34     }
35 //    cout<<f[n][m+1][0];
36 }
37
38 int main()
39 {
40     yyj("hdu1693");
41     cin>>T;
42     for (llg t=1;t<=T;t++)
43     {
44         scanf("%lld%lld",&n,&m);
45         for (llg i=1;i<=n;i++) for (llg j=1;j<=m;j++) scanf("%lld",&g[i][j]);
46         dp();
47         printf("Case %lld: There are %lld ways to eat the trees.\n",t,f[n][m][0]);
48     }
49     return 0;
50 }
时间: 2024-12-06 23:02:44

【HDU】1663 Eat the Trees的相关文章

【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】2147 kiki&#39;s game

http://acm.hdu.edu.cn/showproblem.php?pid=2147 题意:n×m的棋盘,每次可以向左走.向下走.向左下走,初始在(1, m),n,m<=2000,问先手是否胜利. #include <cstdio> using namespace std; int main() { int n, m; while(scanf("%d%d", &n, &m), n|m) (n&1)&&(m&1)?

【HDU】4923 Room and Moor(2014多校第六场1003)

Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 263    Accepted Submission(s): 73 Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0

【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因是不愿意写暴力推断的).. 首先是简单的行列建边.源点向行建边.容量为该行元素和,汇点和列建边.容量为该列元素和.全部的行向全部的列建边,容量为K. 跑一次最大流.满流则有解,否则无解. 接下来是推断解是否唯一. 这个题解压根没看懂.还是暴力大法好. 最简单的思想就是枚举在一个矩形的四个端点.设A.D为主对角

【HDU】4918 Query on the subtree 点分治+树状数组

传送门:[HDU]4918 Query on the subtree 题目分析: 首先,简化问题. 1.求一次到点u的距离不超过d的点的个数.很容易,一次O(NlogN)的点分治便可以完成. 2.多次进行操作1.此时不能每次都O(NlogN)了,太慢了.我们考虑到对于点分治,树的重心一共有logN层,第一层为整棵树的重心,第二层为第一层重心的子树的重心,以此类推,每次至少分成两个大小差不多的子树,所以一共有logN层.而且,对于一个点,他最多只属于logN个子树,也就是最多只属于logN个重心.

【HDU】1754 I hate it ——线段树 单点更新 区间最值

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37448    Accepted Submission(s): 14816 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要

【HDU】 1160 FatMouse&#39;s Speed (DP)

一开始写的dfs进行记忆化结果不知道怎么进行路径的记录...改成循环就好了 dp[i] = max(dp[j]) + 1 , weight[j] < weight[j] && speed[j] > speed[i] 一开始进行一次排序使得重量递增,这样只需要考虑速度就好了 #include<cstdio> #include<algorithm> using namespace std; const int maxn = 10005; struct Mou

【hdu】Mayor&#39;s posters(线段树区间问题)

需要离散化处理,线段树的区间修改问题. 需要注意的就是离散化的时候,由于给的数字是一段单位长度,所以需要特殊处理(因为线段的覆盖和点的覆盖是不一样的) 比如:(1,10)(1,4) (6,10) 离散化之后是 1 , 4 , 6 , 10 分别离散为 1 2 3 4 覆盖的时候先覆盖1 4 之后覆盖了1 2 之后覆盖了 2 3,结果为2 但是实际上应该是3 13450359 201301052100 2528 Accepted 1140K 985MS C++ 1960B 2014-09-17 1

【HDU】4908 (杭电 BC #3 1002题)BestCoder Sequence ——哈希

BestCoder Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 573    Accepted Submission(s): 201 Problem Description Mr Potato is a coder.Mr Potato is the BestCoder. One night, an amazing s