poj2411 状态压缩-铺地板题型-轮廓线解法(最优)
解法参考博客https://blog.csdn.net/u013480600/article/details/19569291
一种做法是先打出所有的状态,即满足上下配对的所有可能方案,然后再逐行进行枚举计数
dp[i][s]=sum{dp[i-1][t]},t是所有和s配对的状态
打状态时要注意如果i-1的j是0,那么i的j必定是1,i剩下的位置要必须一对对填入1,也可以用0填入,即枚举i行的横放砖块的起始位置k即可,如果i-1的k或k+1有一个不是1,那么显然不能放下
/*
对于每一行,用11表示一个横放的方块,用0表示竖放方块的第一格,1表示竖放方块的第二格
枚举i-1行的状态,推出i行的状态
如果i-1行的j位置是0,那么第i行的j必须是1,第i行剩下的地方要么填连续两个1要么填0
第n行的状态必须都是1
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
ll dp[][<<];
int n,m,w,path[][];//所有可能的配对方案
void get(int m){
for(int i=;i<=(<<m)-;i++)
for(int j=;j<=(<<m)-;j++){
int ok=;
for(int k=;k<m;k++)
if(ok){
if( !(i&(<<k)) ){//i的第k位是0
if(!(j&(<<k))){
ok=;break;
}
}
else{//i的第k位是1,其实是在枚举j状态横放的起点位置
if(!(j&(<<k)))continue;//j的第k位是0
++k;
if(k>=m || !(i&(<<k))){//i没有第k+1位或者i的第k+1位是0,所以j在k位置不可能横放了
ok=;break;
}
else if( (j&(<<(k-))) && !(j&(<<k)) ){//j的状态是10,显然不可能
ok=;break;
}
}
}
if(ok)path[w][]=i,path[w++][]=j;
}
}
int main(){
while(cin>>n>>m,n){
w=;
if(m>n)swap(n,m);
get(m);
memset(dp,,sizeof dp);
dp[][(<<m)-]=;
for(int i=;i<n;i++)
for(int j=;j<w;j++)
dp[i+][path[j][]]+=dp[i][path[j][]];
printf("%lld\n",dp[n][(<<m)-]);
}
}
另外一种解法
/*
用0和1表示某个位置放不放砖块,如果是0则表示让下一行来补,如果是1则有两种可能,一种是横放,一种是填补上一行的0
对应这三种情况,可以搜索出所有可能的配对情况
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll dp[][<<];
int path[][],n,m,w;
void get(int c,int pre,int now){
if(c>m)return;
else if(c==m){
path[w][]=pre;
path[w++][]=now;
return;
}
get(c+,(pre<<)|,now<<);//后一行不放,前一行必定是1
get(c+,pre<<,(now<<)|);//前一行0,后一行必定是1
get(c+,(pre<<)|,(now<<)|);//前一行横放,后一行也是横放
}
int main(){
while(cin>>n>>m,m){
w=;
if(m>n)swap(n,m);
get(,,);
memset(dp,,sizeof dp);
dp[][(<<m)-]=;//初始条件不可忽略!
for(int i=;i<n;i++)
for(int j=;j<w;j++)
dp[i+][path[j][]]+=dp[i][path[j][]];
printf("%lld\n",dp[n][(<<m)-]);
}
}
最后是轮廓线解法:遍历一次方格,每扫到一个方格时枚举所有可能的轮廓线,然后由上一个格子(上一个状态的轮廓线)推出当前状态的轮廓线所对应的摆放方案数,以此推到最后一个格子
使用滚动dp数组,覆盖之前无效的信息即可
/*
轮廓线解法
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
ll dp[][<<];
int n,m,cur;
void update(int a,int b){//a是包含m位的旧状态,b是包含m+1位的新状态
if(b&(<<m))//如果b的首位是1才进行转移,即如果b的首位是0的话是不成立的
dp[cur][b^(<<m)]+=dp[cur^][a];
}
int main(){
while(cin>>n>>m,m){
if(m>n)swap(m,n);
memset(dp,,sizeof dp);
cur=;
dp[][(<<m)-]=;//边际条件算第一种方案:需要由这个初始状态推导出其他状态
for(int i=;i<n;i++)
for(int j=;j<m;j++){
cur^=;
memset(dp[cur],,sizeof dp[cur]);//把上一轮的状态清零
for(int k=;k<(<<m);k++){//枚举当前所有可能的轮廓线状态
//三种可能
update(k,k<<);//[i,j]不放
if(i && !(k&(<<(m-))))update(k,(k<<)^(<<m)^);//向上摆放
if(j && !(k&))update(k,(k<<)^);//向左摆放
}
}
printf("%lld\n",dp[cur][(<<m)-]);
}
}
poj2411 状态压缩-铺地板题型-轮廓线解法(最优)的更多相关文章
- POJ2411 状态压缩dp
POJ2411 http://poj.org/problem?id=2411
- [ACM_动态规划] 轮廓线动态规划——铺放骨牌(状态压缩1)
Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, af ...
- 状态压缩dp(hdu2167,poj2411)
hdu2167 http://acm.hdu.edu.cn/showproblem.php?pid=2167 给定一个N*N的板子,里面有N*N个数字,选中一些数字,使得和最大 要求任意两个选中的数字 ...
- HihoCoder第九周 状态压缩 二 与POJ2411总结
在此我向各位博友求助,特别想知道除了HihoCoder上面的结果要对1e9+7取余之外,这两道题还有什么其他的问题,都是骨牌覆盖问题,都是状态压缩+dp,为什么我能过poj2411的程序过不了Hiho ...
- 转 状态压缩DP
引入 首先来说说“状态压缩动态规划”这个名称,顾名思义,状态压缩动态规划这个算法包括两个特点,第一是“状态压缩”,第二是“动态规划”. 状态压缩: 从状态压缩的特点来看,这个算法适用的题目符合以下的条 ...
- 状态压缩dp小结
最近一段时间算是学了一些状态压缩的题目,在这里做个小结吧 首先是炮兵布阵类题目,这类题目一开始给定一个矩形,要求在上面放置炮兵,如果在一格放了炮兵那么周围的某些格子就不能放炮兵,求最大能放置炮兵的数量 ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- hdu1565 网络流或状态压缩DP
对于网络流有一个定理: 最小点权覆盖集=最大网络流: 最大点权独立集=总权值-最小点权覆盖集: 网络流解法代码如下: #include<cstdio> #include<iostre ...
- SGU131 - Hardwood floor(状态压缩DP)
题目大意 给定一个N*M大小的矩形,要求你用1*2和2*2(缺个角)的砖块把矩形铺满(不能重叠),问总共有多少种铺法? 题解 受POJ2411的影响,怎么都没想到3,4,5,6这几种情况该怎么放置,看 ...
随机推荐
- es教程
概念 关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields) ...
- sql常用问题(一)
一.sql要掌握 1.sum select sum(score) from table 2.group select name, sum(score) from table group by 3.a ...
- 《SSH网上商城》-视频目录--代码可以跑起来
本课程是2015年2月份的,就是14年底的. 课程第一天的代码-添加 jsp-api.jar servlet-api.jar就可以跑起来,环境 JDK1.7 和tomcat8, SSH网上商城\S ...
- 小程序学习(冒泡,快速创建文件,以及tarbar)
1.关于小程序的事件冒泡机制 例如: <view catchtap="opp"> <text>当前内容</text> </view> ...
- w10谷歌chrome关闭自动更新
运行输入:msconfig打开服务 选择服务,找到谷歌更新 ,点击禁用 ,然后保存 保存会要求重启电脑 ,重启后打开页面谷歌 ,会出现弹窗,是否更新 ,点否 . 然后解决,不会再自动更新了. 这是 ...
- mysql数据库卸载和安装
背景: 由于之前一个项目中用的数据库版本是免安装的mysql5.5.36,但是后来经过第三方测试公司测试出该数据库存在很多漏洞需要升级数据库才能解决.所以觉得将数据库更换为mysql-5.7.21-w ...
- OGG选择捕捉和应用模式
本章包含的信息可帮助您确定适用于数据库环境的捕获和应用模式. 主题: Oracle GoldenGate捕获和应用进程概述 决定使用哪种捕捉方法 决定使用哪种应用方法 同时使用不同的捕捉和应用模式 切 ...
- Intel Xeon E5-2620 v4参数
基本参数 CPU系列 Xeon E5 v4系列 制作工艺 14纳米 核心代号 Broadwell 性能参数 核心数量 八核心 线程数量 十六线程 CPU主频 2.1GHz 动态加速频率 3GHz L3 ...
- QML 从入门到放弃
发现了一个问题: QQuickView only supports loading of root objects that derive from QQuickItem. If your examp ...
- SSH命令行管理文件
1.从服务器上下载文件 ssh root@13.111.122.133 2.从服务器上下载文件 scp username@servername:/path/filename /var/www/loca ...