PKU P2411 Mondriaan's Dream

题目描述:

Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series' (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways.

Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!

输入格式:

The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0.

输出格式:

For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.

样例输入:

1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0

样例输出:

1
0
1
2
3
5
144
51205

提示:

1<=h,w<=11

时间限制:1000ms
空间限制:256MByte


来源:PKU

这道题本来几个月前就应该做掉的,可是自己那时候太弱了,只有现在重新刷一下了。。。

结果自己写的方法和网上的题解感觉有些不一样,我是用已知的一行去推算下一行的情况;

注意(除第一行):如果一行中有1,这个1可能代表这两种情况,一种是横着放,一种是上面一排竖下来的(那么上面一排的这个位置肯定是0),所以转移的时候要注意下下;

记住,0永远只代表着从这行竖着向下放的方块!!!(前几个月这个一直没想清楚,还想用三进制的做,真是NAIVE)

#include<bits/stdc++.h>
#define ll long long
using namespace std; ll n,m,f[][<<];
ll maxn; ll find(ll val)
{
ll t = ;
for(ll i=;i<m;i++)
{
ll ce = << i;
if(val & ce) t++;
else
{
if(t & ) return ;
t = ;
}
}
return ;
} ll check(ll now , ll down)
{
ll t = ;
for(ll i=;i<m;i++)
{
ll ce = << i;
if(down & ce)
{
if(now & ce)
t++;
else
{
if(t & ) return ;
t = ;
}
}
else
{
if(!(now & ce)) return ;
if(t & ) return ;
t = ;
}
}
if(t & ) return ;
return ;
} int main(){
while(~scanf("%lld%d",&n,&m))
{
if(!n && !m) return ;
if(n * m & )
{
cout<<<<endl;
continue;
}
memset(f,,sizeof(f));
maxn = << m;
for(ll i=;i<maxn;i++)
if(find(i))
f[][i] = ;
for(ll i=;i<n;i++)
for(ll j=;j<maxn;j++)
{
if(f[i][j])
for(ll k=;k<maxn;k++)
{
if(check(j , k))
f[i + ][k] += f[i][j];
}
}
printf("%lld\n",f[n][maxn-]);
}
}

然后这个代码刚好跑过去,吓死我啦。

可是我有想了想,总觉得我这个代码还可以优化。

如果是从这一行推下一行的话,那么第一行为什么还要重新推一次呢?

直接从第〇行开始不就好了吗???

还是NAIVE 啊 啊啊!

于是我把我的代码删了一部分,修改一点点,真的的就一点点。。。

#include<bits/stdc++.h>
#define ll long long
using namespace std; ll n,m,f[][<<];
ll maxn; ll check(ll now , ll down)
{
ll t = ;
for(ll i=;i<m;i++)
{
ll ce = << i;
if(down & ce)
{
if(now & ce)
t++;
else
{
if(t & ) return ;
t = ;
}
}
else
{
if(!(now & ce)) return ;
if(t & ) return ;
t = ;
}
}
if(t & ) return ;
return ;
} int main(){
while(~scanf("%lld%d",&n,&m))
{
if(!n && !m) return ;
if(n * m & )
{
cout<<<<endl;
continue;
}
memset(f,,sizeof(f));
maxn = << m;
f[][maxn-] = ;
for(ll i=;i<n;i++)
for(ll j=;j<maxn;j++)
{
if(f[i][j])
for(ll k=;k<maxn;k++)
{
if(check(j , k))
f[i + ][k] += f[i][j];
}
}
printf("%lld\n",f[n][maxn-]);
}
}

结果却。。。

还是NAIVE啊!!!

PKU P2411 Mondriaan's Dream的更多相关文章

  1. [poj P2411] Mondriaan's Dream

    [poj P2411] Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18023   A ...

  2. PKU 2411 Mondriaan's Dream 状态DP

    以前做过这题,今天又写了一次,突然发现写了一个好漂亮的DFS……(是不是太自恋了 - -#) 代码: #include <cstdio> #include <cstring> ...

  3. POJ 题目2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13519   Accepted: 787 ...

  4. HDU 1400 (POJ 2411 ZOJ 1100)Mondriaan's Dream(DP + 状态压缩)

    Mondriaan's Dream Problem Description Squares and rectangles fascinated the famous Dutch painter Pie ...

  5. POJ2411 Mondriaan's Dream(状态压缩)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15295   Accepted: 882 ...

  6. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  7. POJ2411 铺地砖 Mondriaan's Dream

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15962   Accepted: 923 ...

  8. POJ 2411 Mondriaan's Dream 插头dp

    题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...

  9. 【POJ2411】Mondriaan's Dream(轮廓线DP)

    [POJ2411]Mondriaan's Dream(轮廓线DP) 题面 Vjudge 题解 这题我会大力状压!!! 时间复杂度大概是\(O(2^{2n}n^2)\),设\(f[i][S]\)表示当前 ...

随机推荐

  1. try...catch语句

    程序的异常:Throwable 严重问题Error我们不处理,这种问题一般都是很严重的,比如内存溢出 问题Exception 编译期问题不是RuntimeException的异常必须进行处理,如果不处 ...

  2. MySQL使用命令导出/导入数据

    导出数据库文件 常用命令 mysqldump -uroot -pMyPassword databaseName tableName1 tableName2 > /home/foo.sql mys ...

  3. 搭建 Git 服务器(基于 CentOS 7)

    服务器上的-Git-架设服务器-官网参考 对于规模比较小的团队,可以直接搭建 Git 服务器,逐个收集研发同学的证书配置进来即可.如果团队规模比较大,可以直接采用 GitLab.Drone 等现成的带 ...

  4. 000 (H5*) 知识点总结

    https://note.youdao.com/ynoteshare1/index.html?id=ff02e616917fba868f39241c8383d7c7&type=note 目录 ...

  5. Java第四周编程总结

    第四周编程总结 1.写一个名为Rectangle的类表示矩形.其属性包括宽width.高height和颜色color,width和height都是double型的,而color则是String类型的. ...

  6. 移动端自动化测试之Appium的工作原理学习

    Appium 简介 参考官网文档说明:http://appium.io/docs/en/about-appium/intro/ Appium官方文档上介绍,Appium 是一个自动化测试的开源工具,支 ...

  7. [2019杭电多校第七场][hdu6655]Just Repeat

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6655 题意是说两个人都有一些带有颜色的牌,两人轮流出牌,但是不能出对面出过的颜色的牌,最后谁不能出牌谁 ...

  8. CodeForces 877E DFS序+线段树

    CodeForces 877E DFS序+线段树 题意 就是树上有n个点,然后每个点都有一盏灯,给出初始的状态,1表示亮,0表示不亮,然后有两种操作,第一种是get x,表示你需要输出x的子树和x本身 ...

  9. BZOJ 4919 (树上LIS+启发式合并)

    题面 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i, ...

  10. java 中的引用类型

    GC基本原理 GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征 ...