• poj2411 Mondriaan's Dream


    Mondriaan's Dream

    Time Limit: 3000MS Memory Limit: 65536K

    Description

    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!

    Input

    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. Otherwise, 1<=h,w<=11.

    Output

    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.

    Sample Input

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

    Sample Output

    1
    0
    1
    2
    3
    5
    144
    51205

    Source

    Ulm Local 2000

    这可能是一道轮廓线dp的经典题。
    我更愿意把他叫做贪吃蛇233,显然是因为他的走的路线有点像贪吃蛇啊233
    具体是怎么样的呢?显然其他思路不是很科学,所以我们来学一种新的姿势。

    对于每一个dp状态,你可以看成你有一条蛇在这个地图上爬。由于你每个格子只有两种状态,已覆盖和没有被覆盖(1或0),所以你可以状压。

    地图:
    1 2 3
    4 5 6
    7 8 9

    你的路线:
    1 2 3
    2 3 4
    3 4 5
    4 5 6
    5 6 7
    6 7 8
    7 8 9

    你蛇的长度是什么呢?是你的地图的宽度。
    这样有什么好处呢? 你可以保证每一列你都有身体的一部分在这个上面。
    那么又为什么要这样呢?你可以思考一下就会发现,假设你蛇现在在5 6 7,你即将走8,由于题目你每个格子可以分成向上放,向左放,和不放。
    向上放:你需要保证你上方的格子已经被覆盖了才可以(不然你上面的格子就没有机会被覆盖了)。
    向左放:首先你需要保证你不是最左边的格子,然后你左边的格子没有被覆盖,上面的格子已经被覆盖了。
    不放:你只需要保证你上面的格子被覆盖了。。。
    综上,你会发现你的转移有且仅与你的上一次转移有关系,所以你蛇的长度正好可以保证保留一整套完整的状态。当然,也就可以滚动数组了。
    感觉妙妙的样子~
    感觉自己位运算的能力提高了(原来应该是没有233)

    
    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = (1 << 11);
    int n, m, d, lim;
    long long dp[2][maxn];
    
    inline int clear(int t, int a)
    {
    	return (t ^ (1 << (a - 1)));
    }
    
    inline bool check(int t, int a)
    {
    	return (1 & (t >> (a - 1)));
    }
    
    inline int workk(int t)
    {
    	int ret = clear(t, m);
    	ret <<= 1; ret |= (1 << 1); ret |= 1; 
    	return ret;
    }
    
    int main()
    {
    	while(~scanf("%d%d", &n, &m))
    	{
    		if(n == 0) return 0;
    		memset(dp, 0, sizeof(dp)); d = 0; dp[d][(1 << m) - 1] = 1; lim = (1 << m);
    		for(int i = 1; i <= n; ++i)
    		{
    			for(int j = 1; j <= m; ++j)
    			{
    				d ^= 1; memset(dp[d], 0, sizeof(dp[d]));
    				for(int k = 0; k < lim; ++k)
    				{
    					if(check(k, m)) 
    					{
    						dp[d][clear((k << 1), m + 1)] += dp[d ^ 1][k];
    					} 	
    					if(!check(k, m)) 
    					{
    						dp[d][((k << 1) + 1)] += dp[d ^ 1][k];
    					} 	
    					if(!check(k, 1) && check(k, m) && (j != 1))
    					{
    						dp[d][workk(k)] += dp[d ^ 1][k];
    					} 
    				}
    			}
    		}
    		printf("%lld
    ", dp[d][(1 << m) - 1]);
    	} 
    	return 0;
    } 
    
    
    心如花木,向阳而生。
  • 相关阅读:
    嵌入式MicroFlighter 之STM32F103学习——编写第一个STM32程序
    嵌入式stm32学习方法
    嵌入式stm32学习之路(led流水灯工程)
    嵌入式stm32 LED 流水灯剖析(库函数版)
    Swift快速入门(一)第一个Swift程序
    从库函数方向入门stm32的个人建议
    嵌入式STM32使用PWM控制LED呼吸灯效果
    嵌入式STM32学习笔记之按键查询方式控制led灯的亮灭
    从零写一个编译器(完结):总结和系列索引
    从零写一个编译器(十三):代码生成之遍历AST
  • 原文地址:https://www.cnblogs.com/LLppdd/p/8622243.html
Copyright © 2020-2023  润新知