HDU 1693 Eat the Trees
来源:互联网 发布:淘宝swatch官方旗舰店 编辑:程序博客网 时间:2024/05/19 10:12
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1693
题意:给一个n*m的地图,1可走,0不可走。现在可以在地图上构建若干条回路,使得覆盖所有的1,不覆盖任何一个0,而且每个1只能被覆盖一次,求不同的方案。
思路:比较简单的插头dp,0的格子无连通,1的格子一定有两个连通(在回路中)。分类转移即可。
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long longconst int maxn = 4111;int n , m;int cur , pre;int g[20][20];struct hashtable{ int head[maxn] , next[maxn] , state[maxn] , size; LL value[maxn]; void clear() { Clean(head,-1); size = 0; } void push( int S , LL V ) { int h = S % maxn; for( int k = head[h]; k != -1; k = next[k] ) if ( state[k] == S ) { value[k] += V; return; } state[size] = S , value[size] = V; next[size] = head[h] , head[h] = size++; }}dp[2];void DP( int x , int y , int k ){ int S = dp[pre].state[k]; LL V = dp[pre].value[k]; int left = S & (1<<(y-1)) , up = S & (1<<y); S = S ^ left ^ up; //去掉左边和上边的状态 //S状态转移到下一格时,只有第y位和y-1位可能改变,所以先把y和y-1位变为0,根据需求再添加 if ( !g[x][y] ) { if ( !left && !up ) dp[cur].push( S , V ); //右 下无连通,y 和 y-1位为0 } else { if ( !left && !up ) //无连通 , 右下必须要都连通 { //如果右下可以满足连通条件 if ( x < n && y < m && g[x+1][y] && g[x][y+1] ) dp[cur].push( S^(1<<y)^( 1<<(y-1) ) , V ); } else if ( !left || !up ) //单连通 , 分别尝试右和下连通 { if ( x < n && g[x+1][y] ) dp[cur].push( S^( 1<<(y-1) ) , V ); if ( y < m && g[x][y+1] ) dp[cur].push( S^(1<<y) , V ); } else dp[cur].push( S , V ); //双联通 , 右下无连通 }}void solve(){ cur = 0 , dp[cur].clear(); dp[0].push( 0 , 1 ); rep(i,1,n) { pre = cur , cur ^= 1; dp[cur].clear(); for( int k = 0; k < dp[pre].size; k++ ) dp[cur].push( dp[pre].state[k]<<1 , dp[pre].value[k] ); rep(j,1,m) { pre = cur , cur^=1 , dp[cur].clear(); for( int k = 0; k < dp[pre].size; k++ ) DP( i , j , k ); } } LL ans = 0; for( int k = 0; k < dp[cur].size; k++ ) if ( dp[cur].state[k] == 0 ) {ans = dp[cur].value[k];break;} printf("There are %lld ways to eat the trees.\n",ans);}int main(){ int T; cin>>T; rep(cas,1,T) { scanf("%d%d",&n,&m); rep(i,1,n) rep(j,1,m) scanf("%d",&g[i][j]); printf("Case %d: ",cas); solve(); } return 0;}
0 0
- hdu 1693 Eat the Trees
- hdu 1693 Eat the Trees
- hdu 1693 Eat the Trees
- HDU 1693 Eat the Trees
- 【HDU 1693】Eat the Trees
- HDU 1693 Eat the Trees
- HDU 1693 Eat the Trees
- HDU 1693 Eat the Trees
- HDU-1693 Eat the Trees 插头DP
- HDU 1693 Eat the Trees 插头DP
- HDU 1693 Eat the Trees 插头DP
- hdu 1693 Eat the Trees 插头dp
- hdu 1693 Eat the Trees 插头dp
- HDU 1693(Eat the Trees-不用匹配的插头Dp)
- hdu 1693 Eat the Trees 轮廓线 插头dp
- hdu 1693 Eat the Trees 插头dp入门题
- hdu 1693 Eat the Trees (插头dp入门)
- HDU 1693 Eat the Trees (插头DP,闭合路径)
- jQuery Datatable 实用简单实例
- 【CodeVS 1038】一元三次方程
- Android项目中的单元测试(Junit4)
- 工作流-JBPM(1)
- OpenGL -- 多颜色的立方体旋转
- HDU 1693 Eat the Trees
- 《驴得水》影评
- netmap源码分析(四)用户态收包过程
- 如何删除属性页和属性表单中的帮助按钮
- Java 数字操作类
- Android NDK开发(一) 入门
- nginx之gzip
- js对象篇(二)
- 数据挖掘学习笔记一:绪论