ZOJ Problem Set - 2563 Long Dominoes 【如压力dp】
称号:ZOJ Problem Set - 2563 Long Dominoes
题意:给出1*3的小矩形。求覆盖m*n的矩阵的最多的不同的方法数?
分析:有一道题目是1 * 2的。比較火。链接:这里
这个差点儿相同,就是当前行的状态对上一行有影响。对上上一行也有影响。所以
定义状态:dp【i】【now】【up】表示在第 i 行状态为now 。上一行状态为 up 时的方案数。
然后转移方程:dp【i】【now】【up】 = sum ( dp【i-1】【up】【uup】 ) 前提是合法
合法性的推断是比較难考虑的一点。由于是1 * 3的。仅仅能横着放和竖着放。
假设横着放。那么上面up 和 uup 的 3 格也必须是满的才行
假设竖着放,那么up 和 uup的当前格必须是空的,注意推断后变化up
假设用简单的枚举dp的话,四层循环会超时。所以我们要用up 和 upp 来深搜构造当前行,这样才干过。
AC代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define INT long long int
const long long N = 9 ;
const int inf = 0x3f3f3f3f;
INT dp[31][1<<N][1<<N];
int m,n;
bool Judge(int s,int up,int upp)
{
for(int i=s;i<s+3;i++)
if(!(up&(1<<i)) || !(upp&(1<<i)))
return false;
return true;
}
void dfs(int st,int cnt,int now,int up,int upp,INT num)
{
if(cnt==m)
{
dp[st][now][up]+=num;
return ;
}
if(cnt+3<=m && Judge(cnt,up,upp)) //heng
dfs(st,cnt+3,now|(1<<cnt)|(1<<(cnt+1))|(1<<(cnt+2)),up,upp,num);
if(!(up&(1<<cnt))&&!(upp&(1<<cnt))) // 竖放
dfs(st ,cnt+1 ,now|(1<<cnt) ,up|(1<<cnt) ,upp , num) ;
if(upp&(1<<cnt)) //留空
dfs(st ,cnt+1 ,now ,up ,upp ,num) ;
}
int main()
{
while(~scanf("%d%d",&m,&n)&& m+n)
{
memset(dp,0,sizeof(dp));
dfs(1,0,0,(1<<m)-1,(1<<m)-1,1);
for(int i=2; i<=n; i++)
{
for(int up=0; up<(1<<m); up++) //上行
{
for(int st=0; st<(1<<m); st++) //上上行
{
if(dp[i-1][up][st]) //注意一定推断
dfs(i,0,0,up,st,dp[i-1][up][st]);
}
}
}
printf("%lld\n",dp[n][(1<<m)-1][(1<<m)-1]);
}
return 0;
}
枚举超时代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define INT long long int
const long long N = 9 ;
const int inf = 0x3f3f3f3f;
INT dp[31][1<<N][1<<N];
int m,n;
bool isit(int st)
{
int tmp=0;
for(int i=0;i<m;i++)
{
if(st&(1<<i))
tmp++;
else
{
if(tmp%3)
return false;
}
}
if(tmp%3)
return false;
return true;
}
INT solve(int now,int up,int uup)
{
for(int i=0;i<m;i++)
{
if(!(uup&(1<<i))) //推断上上一行为0
{
if(up&(1<<i))
return -1 ;
else
{
if(!(now&(1<<i)))
return -1 ;
else
up |= (1<<i) ;
}
}
else
{
if(up&(1<<i) && now&(1<<i)) // 1 1 1
{
if(i==m-2 || i==m-1)
return -1 ;
else if(!(now&(1<<(i+1))) || !(now&(1<<(i+2))) || !(up&(1<<(i+1))) || !(up&(1<<(i+2))) || !(uup&(1<<(i+2))) || !(uup&(1<<(i+1))))
return -1 ;
i+=2;
}
}
}
return up ;
}
int main()
{
while(~scanf("%d%d",&m,&n)&& m+n)
{
for(int st=0;st<(1<<m);st++)
{
if(!isit(st))
continue;
for(int up=0;up<(1<<m);up++)
{
if(isit(up)){
dp[2][st][up]=1;
}
}
}
for(int i=3;i<=n;i++)
{
for(int no = 0;no < (1<<m); no++)
{
for(int kp=0;kp<(1<<m);kp++) //上行
dp[i][no][kp]=0;
for(int up=0;up<(1<<m);up++) //上行
{
int temp ;
for(int st=0;st<(1<<m);st++) //上上行
if((temp = solve(no,up,st)) != -1)
dp[i][no][temp]+=dp[i-1][up][st];
//printf("%d\n",dp[i][up][up]);
}
}
}
printf("%lld\n",dp[n][(1<<m)-1][(1<<m)-1]);
}
return 0;
}
版权声明:本文博主原创文章,博客,未经同意不得转载。
ZOJ Problem Set - 2563 Long Dominoes 【如压力dp】的更多相关文章
- ZOJ Problem Set - 2297 Survival 【状压dp】
题目:ZOJ Problem Set - 2297 Survival 题意:给出一些怪,有两个值,打他花费的血和能够添加的血,然后有一个boss,必须把小怪全部都打死之后才干打boss,血量小于0会死 ...
- ZOJ Problem Set - 1394 Polar Explorer
这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...
- ZOJ Problem Set - 1025解题报告
ZOJ Problem Set - 1025 题目分类:基础题 原题地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=10 ...
- ZOJ Problem Set - 3829Known Notation(贪心)
ZOJ Problem Set - 3829Known Notation(贪心) 题目链接 题目大意:给你一个后缀表达式(仅仅有数字和符号),可是这个后缀表达式的空格不幸丢失,如今给你一个这种后缀表达 ...
- ZOJ Problem Set - 3593 拓展欧几里得 数学
ZOJ Problem Set - 3593 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3593 One Person ...
- ZOJ Problem Set - 3820 Building Fire Stations 【树的直径 + 操作 】
题目:problemId=5374" target="_blank">ZOJ Problem Set - 3820 Building Fire Stations 题 ...
- ZOJ Problem Set - 3229 Shoot the Bullet 【有上下界网络流+流量输出】
题目:problemId=3442" target="_blank">ZOJ Problem Set - 3229 Shoot the Bullet 分类:有源有汇 ...
- ZOJ Problem Set - 3822Domination(DP)
ZOJ Problem Set - 3822Domination(DP) problemCode=3822">题目链接 题目大意: 给你一个n * m的棋盘,每天都在棋盘上面放一颗棋子 ...
- ZOJ Problem Set - 3819Average Score
ZOJ Problem Set - 3819Average Score 题目链接 题目大意:给你两个班的的学生的分数(A,B班).A班有一个学生的分数没有给出. 如今要求你给出这个学生分数的上下限.使 ...
随机推荐
- XML语法规范
1: 怎样声明一个xml文件 答:由2部分组成 声明部分,声明xml的版本号与编码(版本号仅仅有1.0) <? xml version="1.0" encoding=&quo ...
- 高效合并两个有序数组(Merge Sorted Array)
Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: Y ...
- NSDictionary、NSMutableDictionary基本使用
郝萌主倾心贡献,尊重作者的劳动成果.请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...
- ImportError: No module named _sqlite3 - 代码分享
ImportError: No module named _sqlite3 - 代码分享 ImportError: No module named _sqlite3 作者:86市场网 点击 ...
- C++ Primer 学习笔记_61_重载操作符与转换 --自增/自减操作符
重载操作符与转换 --自增/自减操作符 引言: 自增,自减操作符常常由诸如迭代器这种类实现,这种类提供相似于指针的行为来訪问序列中的元素.比如,能够定义一个类,该类指向一个数组并为该数组中的元素提供訪 ...
- POJ 2365 Rope(水题)
[题意简述]:给出我们钉子个数与半径,让我们求出缠绕在钉子上的绳子有多长. [分析]:从题目中我们能够看出,绳子长度的和等于每两个钉子的距离的和加上接触在钉子上的绳子的长度,不难发现这部分长度事实上就 ...
- php学习之道:php中soap的使用实例以及生成WSDL文件,提供自己主动生成WSDL文件的类库——SoapDiscovery.class.php类
1. web service普及: Webservice soap wsdl差别之个人见解 Web Service实现业务诉求: Web Service是真正"办事"的那个,提供 ...
- poj1849(求树的直径)
题目链接:http://poj.org/problem?id=1849 题意:有一颗n个结点的带权的无向树, 在s结点放两个机器人, 这两个机器人会把树的每条边都走一遍, 但是最后机器人不要求回到出发 ...
- HDU 5066 Harry And Physical Teacher(物理题)
HDU 5066 Harry And Physical Teacher 思路:利用物理里面的动量守恒公式.因为保证小车质量远大于小球.所以能够把小车质量当成无穷大带进去,得到答案为2 * v0 - v ...
- FMOD在Android玩音响系统的抖动问题
1. 基本介绍 在Android升级系统Android4.4之后,发现FMOD在Android音会出现抖动.导致声音不正常.边赫赫有名的"极品飞车"都有问题. 经查验,是FMOD的 ...