#插头dp#洛谷 5074 HDU 1693 Eat the Trees
题目
给出 \(n*m\) 的方格,有些格子不能铺线,
其它格子必须铺,可以形成多个闭合回路。
问有多少种铺法? \(n,m\leq 12\)
分析
设 \(dp[n][m][S][0/1]\) 表示处理到 \((n,m)\),
目前插头的状态为 \(S\),并且左插头是否向右暴露,
插头的状态指的是轮廓线上的上插头是否向下暴露,这个分类讨论一下就可以了,
注意到右边界的位置左插头不能向右暴露,并且不能铺线的地方要继续更新方案
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
int n,m,al,a[12][12];
long long dp[4101][2],f[4101][2];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
signed main(){
for (rr int T=iut();T;--T){
memset(dp,0,sizeof(dp));
n=iut(),m=iut(),al=1<<m,dp[0][0]=1;
for (rr int i=0;i<n;++i)
for (rr int j=0;j<m;++j)
a[i][j]=iut();
for (rr int i=0;i<n;++i)
for (rr int j=0;j<m;++j){
if (a[i][j]){
for (rr int k=0;k<al;++k)
if ((k>>j)&1){
f[k][0]+=dp[k][0];//|
f[k^(1<<j)][1]+=dp[k][0];//L
f[k^(1<<j)][0]+=dp[k][1];//>
}else{
f[k][1]+=dp[k][1];//-
f[k|(1<<j)][0]+=dp[k][1];//7
f[k|(1<<j)][1]+=dp[k][0];//<
}
}else{
for (rr int k=0;k<al;++k)
if (!((k>>j)&1))
f[k][0]=dp[k][0];//不存在插头
}
if (j==m-1){
for (rr int k=0;k<al;++k)
f[k][1]=0;//不能有暴露的左插头
}
memcpy(dp,f,sizeof(dp));
memset(f,0,sizeof(f));
}
printf("%lld\n",dp[0][0]);
}
return 0;
}
简化
可以发现,dp数组能够被压成一维,记录 \(m+1\) 个插头,
轮廓线往右移动一格左插头也向右移动一个。
注意位于行末时需要移除右侧插头并补上左侧插头,即调整轮廓线的状态
代码(HDU 1693)
#include <cstdio>
#include <cctype>
using namespace std;
int T,two[14],n,m,al;
long long f[8192],dp[8192];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
int main(){
T=iut(),two[0]=1;
for (int i=1;i<=13;++i) two[i]=two[i-1]<<1;
for (int _T=1;_T<=T;++_T){
n=iut(),m=iut(),al=two[m+1]-1;
for (int i=0;i<=al;++i) f[i]=0; f[0]=1;
for (int i=0;i<=al;++i) dp[i]=f[i];
for (int i=0;i<n;++i)
for (int j=0;j<m;++j){
int x=iut();
for (int S=0;S<=al;++S) f[S]=0;
for (int S=0;S<=al;++S)
if (dp[S]){
bool zuo=(S>>j)&1,upp=(S>>(j+1))&1;
if (x){
f[S^two[j]^two[j+1]]+=dp[S];//转弯
if (zuo!=upp) f[S]+=dp[S];//直行
}else if (!zuo&&!upp) f[S]+=dp[S];
}
for (int S=0;S<=al;++S)
if (j<m-1) dp[S]=f[S];
else dp[S]=(S&1)?0:f[S>>1];//行末最右侧的左插头不存在,插头整体往右移动一格,同时在左侧补上左插头
}
printf("Case %d: There are %lld ways to eat the trees.\n",_T,dp[0]);
}
return 0;
}
#插头dp#洛谷 5074 HDU 1693 Eat the Trees的更多相关文章
- hdu 1693 Eat the Trees——插头DP
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1693 第一道插头 DP ! 直接用二进制数表示状态即可. #include<cstdio> # ...
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
插头DP基础题的样子...输入N,M<=11,以及N*M的01矩阵,0(1)表示有(无)障碍物.输出哈密顿回路(可以多回路)方案数... 看了个ppt,画了下图...感觉还是挺有效的... 参考 ...
- HDU 1693 Eat the Trees(插头DP)
题目链接 USACO 第6章,第一题是一个插头DP,无奈啊.从头看起,看了好久的陈丹琦的论文,表示木看懂... 大体知道思路之后,还是无法实现代码.. 此题是插头DP最最简单的一个,在一个n*m的棋盘 ...
- HDU - 1693 Eat the Trees(多回路插头DP)
题目大意:要求你将全部非障碍格子都走一遍,形成回路(能够多回路),问有多少种方法 解题思路: 參考基于连通性状态压缩的动态规划问题 - 陈丹琦 下面为代码 #include<cstdio> ...
- HDU 1693 Eat the Trees(插头DP,入门题)
Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...
- HDU 1693 Eat the Trees (插头DP)
题意:给一个n*m的矩阵,为1时代表空格子,为0时代表障碍格子,问如果不经过障碍格子,可以画一至多个圆的话,有多少种方案?(n<12,m<12) 思路: 这题不需要用到最小表示法以及括号表 ...
- HDU 1693 Eat the Trees ——插头DP
[题目分析] 吃树. 直接插头DP,算是一道真正的入门题目. 0/1表示有没有插头 [代码] #include <cstdio> #include <cstring> #inc ...
- hdu 1693 : Eat the Trees 【插头dp 入门】
题目链接 题意: 给出一个n*m大小的01矩阵,在其中画线连成封闭图形,其中对每一个值为1的方格,线要恰好穿入穿出共两次,对每一个值为0的方格,所画线不能经过. 参考资料: <基于连通性状态压缩 ...
- HDU 1693 Eat the Trees
第一道(可能也是最后一道)插头dp.... 总算是领略了它的魅力... #include<iostream> #include<cstdio> #include<cstr ...
- 【HDU】1693 Eat the Trees
http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:n×m的棋盘求简单回路(可以多条)覆盖整个棋盘的方案,障碍格不许摆放.(n,m<=11) #i ...
随机推荐
- Mysql 插入timestamp没有使用默认值问题
在一次升级过程中,发现Mysql插入数据报了个错 Column 'create_time' cannot be null. 但是看了下这个字段虽然是非null,但是是有默认值的 `create_tim ...
- rename重命名
[root@liuwei test]# ls 11.txt 12.txt 13.txt 14.txt 15.txt 16.txt 17.txt 18.txt 19.txt 1.txt 20.txt 2 ...
- celery中异步延迟执行任务apply_anysc的用法
描述 首先说下异步任务执行delay()和apply_anysc()两者区别,其实两者都是执行异步任务的方法,delay是apply_anysc的简写.所以delay中传递的参数会比apply_any ...
- 把Customer Order的列表页面的代码,分离到组件里
1.新增Shared文件夹,在Shared下新增OrdersListView.razor 2.在_Imports.razor文件里添加一行 3.重命名Pages/Trade目录下的OrdersList ...
- 第一百一十篇:内存泄漏和垃圾回收(JS)
好家伙,本篇内容为<JS高级程序设计>第四章的学习笔记 1.内存泄露 1.1.什么是内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释 ...
- CXPACKET等待类型分析
背景 客户反馈今天8点钟开始进入业务高峰期后,数据库的CPU利用率非常高,基本达到了100%,前端应用也非常慢.怀疑是昨晚业务系统升级导致,请我们紧急协助分析. 现象 登录到SQL专家云,进入相关时间 ...
- RocketMQ(9) 消息堆积与消费延迟
消息堆积与消费延迟 1 概念 消息处理流程中,如果Consumer的消费速度跟不上Producer的发送速度,MQ中未处理的消息会越来越多(进的多出的少),这部分消息就被称为堆积消息.消息出现堆积进而 ...
- Java 开发人员调度软件项目 (java基础编程总结项目)+javaBean+测试代码+数组知识+数据结构+继承+多态+封装+自定义异常,异常处理+构造器知识+重载+重写+接口+实现接口+关键字使用(static +equalsIgnoreCase+fianl+instanceof判断类型)+向下转型与向上转型
/** * * @Description Java 开发人员调度软件项目 (java基础编程总结项目) * +javaBean+测试代码+数组知识+数据结构+继承+多态+封装+自定义异常,异常处理 * ...
- Java 多线程------测试 Thread中的常用方法 + 线程的优先级:
1 package com.bytezero.threadexer; 2 3 import javax.sound.midi.Soundbank; 4 5 /** 6 * 测试 Thread中的常用方 ...
- 9、zookeeper的核心ZAB协议
ZAB协议 zab协议的全称是 Zookeeper Atomic Broadcast (zookeeper原子广播).zookeeper是通过zab协议来保证分布式事务的最终一致性 1.ZAB协议是专 ...