NYOJ_515_完全覆盖_剖析大神的代码

news/2024/7/6 1:41:44

大神的解题报告:http://hi.baidu.com/newmyl/item/afc7cb0ef6ef5b7dbee97e07

1、当高度(h)和宽度(w)为奇数时:

area=h*w;

骨牌面积:2

h*w / 2!=0  -> 不能用骨牌覆盖

2、记f[i][s1]为第i-1行全满且第i行状态为s1时的种数,f[i-1][s2]为第i-2行全满且第i-1行状态为s2时的种数,则骨牌的覆盖方案数会等于f[h][w<<1-1](第h行全满状态):

结论:第i行的放置方案数,取决于第i-1行的放置方案数

对于每一个位置,3种放置方案:

 1. 竖直放置

 2. 水平放置

 3. 不放置

d为当前列号 ,初始化d, s1, s2都为0;对应以上三种放置方法,s1, s2的调整为:

1. d = d + 1, s1 << 1 | 1, s2 << 1;

2. d = d + 2, s1 << 2 | 3, s2 << 2 | 3;

3. d = d + 1, s1 << 1,   s2 << 1 | 1;

先就第一种情况解释一下,另外的两种情况可以类推

S1<<1|1即为把s1的二进制表示后面加上一个1,对就于本题来说就是(d+1)列上放

置,s2<<1即为把s2的二进制表示后面加上一个0,对于本题来说就是(d+1)列上不放置。

但为什么s1、s2会如此变化呢?s1对应于本行的状态,s2对应于上一行的状态,能竖直放置意味着上一行的(d+1)列是空着的,因此此时上一行的状态为s2<<1,同时竖置放置了之后,则本行(d+1)行放置了东西,状态于是变为s1<<1|1;

3、初始时的f值,可以假设第0行全满,第一行只有两种放法:

 1. 水平放置 d = d + 2, s << 2 | 3;
 2. 不放置   d = d + 1, s << 1;

# include <stdio.h>
# include <string.h>
long long a[2][3000];
int t,n,m;
void dfs(int d,int mm) //d列号 
{
if(d==m) 
{
   a[0][mm]++;//使用了滚动数组,当然是a[0]咯
   return;
}
if(d+1<=m)
   dfs(d+1,mm<<1);
if(d+2<=m)
   dfs(d+2,mm<<2|3);
}
void DFS(int d,int mm,int nn)//mm对应于上一行状态,nn对应于下一行状态
{
if(d==m)
{
   a[t][nn]+=a[(t+1)%2][mm];
   return;
}
if(d+1<=m) //判断防越界
{
   DFS(d+1,mm<<1,nn<<1|1); //第一种放置
   DFS(d+1,mm<<1|1,nn<<1); //第三种放置
}
if(d+2<=m) 
   DFS(d+2,mm<<2|3,nn<<2|3); //第二种放置
} 
int main()
{
int i;
while(scanf("%d%d",&n,&m)&&n&&m)
{
   if((n*m)%2)
   {
    printf("0\n");
    continue;
   }
   if(n>m) //当输入的 w > h 时,对调,因为横向的运算是指数级的, 而列向的是线性的.
    n^=m,m^=n,n^=m; //相当于swap(n,m)
   memset(a,0,sizeof(a));
   dfs(0,0);  //初始化第一行
   for(i=2;i<=n;i++)
   {
    t=(i+1)%2;
    DFS(0,0,0);
    memset(a[(t+1)%2],0,sizeof(a[0]));
   }
   printf("%I64d\n",a[(n+1)%2][(1<<m)-1]); //过不了就用cout
} return 0; }

 

转载于:https://www.cnblogs.com/A-way/archive/2013/05/07/3064099.html


http://www.niftyadmin.cn/n/639955.html

相关文章

windows上如何用HDC获得某张图片上某个点的像素值

最近几天在用dark gdk做入门游戏开发&#xff0c;现在就其中遇到的这个问题来说一说 dark gdk没有提供获得某张图片上某个点像素值的函数和接口&#xff0c;所以我想了两种办法&#xff0c; 第一种是先把这张图片通过dbLoadImage和dbPasteImage将这张图片显示出来&#xff0c…

在Linux Debian 8下部署基于PHP的Web项目。

折腾了大半天&#xff0c;总算把项目部署到了服务器上&#xff0c;这里写一篇文章记录一下&#xff0c;当作做学习笔记&#xff0c;同时也给其他想要部署项目的朋友一点思路。目前Linux系统的分支比较多&#xff0c;我了解到的目前分为Debian、Ubuntu等和RedHat、centnOS等。他…

批处理脚本运行出现The system cannot write to the specified device错误

用批处理写好脚本之后&#xff0c;运行报错 “The system cannot write to the specified device” 主要是编码格式的问题&#xff0c;脚本的编码格式与cmd的编码格式不一致&#xff0c;批处理脚本默认的编码格式为ANSI&#xff0c;运行时即使不报错也容易出现乱码&#xff0c…

解决Ubuntu16.04卡在开机画面

首先&#xff0c;开机时发现卡在下图的Ubuntu图标画面&#xff1a; 重启&#xff0c;疯狂按ESC键&#xff0c;在“Ubuntu高级选项”中&#xff0c;按回车&#xff0c;选择执行 带有“&#xff08;recovery mode&#xff09;”的选项&#xff0c;继续回车。 这里我使用的是 老内…

C语言之对char*与char[]的理解

本文实例分析了C语言中char * 和 char []的区别。分享给大家供大家参考之用。具体分析如下&#xff1a; 一般来说&#xff0c;很多人会觉得这两个定义效果一样&#xff0c;其实差别很大。以下是个人的一些看法&#xff0c;有不正确的地方望指正。 本质上来说&#xff0c;char…

leetcode - 7. Reverse Integer

Reverse Integer 知识点32位有符号整型的取值范围是[−2^31, 2^31 − 1] 具体到python中的表现就是&#xff1a;type(pow(2, 31)) 是 long类型。注意如果是type(pow(2, 31)/2)仍为long类型.n次方&#xff1a;2** 31 或 pow(2, 31)绝对值函数abs字符串反转a[::-1]反转字符串的方…

一个很简单的问题,曾经不知道,现在明白了

算是写给自己看的吧~~ 首先这个是我在大一的时候编程的时候发现的&#xff0c;在编译其中&#xff0c;你如果声明一个 int a[1000000](或者是更大&#xff0c;这个得看编译器了&#xff09; 编译器是回报错的&#xff0c;说是overflow的&#xff0c;当时也没注意为什么&…

想学编程?这样开始 Want to learn to code? Start here.

《转》 去年九月我写了一篇挺受欢迎的博文&#xff0c;叫 《想学Rails? 这样开始》。 许多读者看完文章后&#xff0c;当面或用Email向我提了大量问题&#xff1b;也有很多人真正投入到了Rails学习中。我也很自豪地向很多人推荐了这篇文章&#xff0c;因为其中的内 容真的具有…