| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5714 人关注过本帖, 1 人收藏
标题:瓷砖覆盖地面问题
只看楼主 加入收藏
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:30 
解决此题的预备知识:1、动态规划 2、位运算

然后局限性:min(n,m)不能太大

首先我们可以注意到,一块砖只会影响上下两行的,我们设为n行m列(n>=m)的一个地面要铺满瓷砖,如果动态规划的话,我们可以这样想,用S表示某一行的状态,f[i,S]表示表示前i-1行都铺满的情况下,第i行状态为S有多少种铺出来的可能,那么,有动态规划可知,f[i,S]=SUM{f[i-1,S’]}  (当由f[i-1,S’]状态可以到达f[i,S]状态时)。
边界条件:f[1,0]=1; 答案:f[n+1,0]

然后就是状态S的表示,对于某一行的格子,只有两种状态:被铺了或者没有,我们用0和1表示,那么m列就表示为一个m位的2进制数。则使用一个f[1..n,0..2^m-1]的数组存储,如果要节省空间可以使用滚动数组。

具体实现时可以有状态f[i,S]开始搜索,对状态S搜索所有可能的铺满方案(即让S->2^m-1),同时记录下一行的状态S1,然后累加。具体参见写的程序,我写了很多注释,这里不大好说。

程序代码:
#include <stdio.h>
#include <stdlib.h>

int f[12][1024];  //最多支持10行10列   1023=2^10-1
int n,m,i,j;

void dfs(int dep,int now,int next)       //搜索第dep位,现在这行的状态,下一行的状态
{
      if (dep==m)
      {
                 f[i+1][next]+=f[i][j]; return;
      }         //已搜索m位,状态转移
      
      if (now&(1<<dep)) 
      {
                        dfs(dep+1,now,next); return;
      }         //第dep位为1,即已铺过东西,跳到下一位
      
      dfs(dep+1,now|(1<<dep),next|(1<<dep));   //在第dep位竖直铺一块砖,影响下一行的状态 
      
      if (((now&1<<dep)==0) && ((now&1<<(dep+1))==0) && (dep+1<m))
         dfs(dep+2,now|(1<<dep)|1<<(dep+1),next);    //如果可以的话再第dep和dep+1位横着铺一块砖,不影响下一行的状态 
}

 
int main()
{
    scanf("%d%d",&n,&m); 
    memset(f,0,sizeof(f));
    f[1][0]=1;     //边界条件 
    for (i=1; i<=n; i++)
     for (j=0; j<(1<<m); j++)     //状态由0-2^m-1,位运算实现
     if (f[i][j])  dfs(0,j,0);
    printf("%d\n",f[n+1][0]);
    system("pause");
} 

感觉还是没讲大清楚.....

[ 本帖最后由 czz5242199 于 2011-11-16 10:11 编辑 ]
2011-11-15 19:30
waterstar
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:5
帖 子:984
专家分:2810
注 册:2010-2-12
收藏
得分:0 
回复 9楼 laoyang103
老杨不能厚此薄彼啊,先和杨大哥打了招呼,也不和我打个

冰冻三尺,非一日之寒;士别三日,不足刮目相看!
2011-11-15 20:17
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:5 
以下是引用beyondyf在2011-11-15 17:23:45的发言:

你急着要答案吗?

很多贴子我回了之后就没人跟贴了,最多楼主说声谢谢。挺没劲的。

我想看看其他人的解答。尤其像BlueGuy,还有TonyDeng的。

放心,你一定会得到答案的

这题应该可以 DFS, 马跳棋盘玩过吗?
我对做题没有爱啊,想不到其他的方法,...

别人搞个哥德巴赫猜想,难道我也要去整个哥德巴赫猜想 不成??

[ 本帖最后由 BlueGuy 于 2011-11-15 20:31 编辑 ]

我就是真命天子,顺我者生,逆我者死!
2011-11-15 20:26
laoyang103
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:内蒙古包头
等 级:贵宾
威 望:19
帖 子:3082
专家分:11056
注 册:2010-5-22
收藏
得分:2 
以下纯属个人见解 如果不对请多指正
首先根据Cover[2][n] = Cover[2][n-1] + Cover[2][n-2] (Cover[2][1]=1,Cover[2][2]=2) 并且n为偶数

其实这就是个斐波那契数列 1 2 3 5 8 13 34 ......第八个是34也就是Cover[2][8]=34

如果要求Cover[8][8] 可以把它想成 覆盖1*n的地面的方法数乘以覆盖7*n的方法数  加上 覆盖2*n的地面的方法数乘以覆盖6*n的方法数 因为n为偶数所以覆盖1*n的地面的方法数只有一种 覆盖2*n的地面的方法数已经在前面求出

所以Cover[m][n] = Cover[m-1][n] + t*Cover[m-2][n],t = Cover[2][n] 这样递归求解就可以了吧
我求出的的Cover[8][8] = 1700544

[ 本帖最后由 laoyang103 于 2011-11-15 20:46 编辑 ]

                                         
===========深入<----------------->浅出============
2011-11-15 20:26
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 14楼 laoyang103
有重复,如果一个状态第i与i+1行,j与j+1行之间都没有交叉,就会算两次,而且这个公式不是在2列的情况下都错的吗。

[ 本帖最后由 czz5242199 于 2011-11-15 20:33 编辑 ]
2011-11-15 20:30
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 13楼 BlueGuy
dfs时间跟不上,时间复杂度大约是2^(nm)
2011-11-15 20:31
waterstar
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:5
帖 子:984
专家分:2810
注 册:2010-2-12
收藏
得分:0 
回复 11楼 czz5242199
谢谢了,正在研究你的算法。

顺便问句,有没有推导公式什么的,利用上之前提过的f[M]=f[M-1]+f[M-2]这中公式,能快速的手算出大概的种类?

冰冻三尺,非一日之寒;士别三日,不足刮目相看!
2011-11-15 20:31
卧龙孔明
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:59
帖 子:3872
专家分:684
注 册:2006-10-13
收藏
得分:10 
生成函数可直接得到公式,参考具体数学

My Blog: www.aiexp.info
虽然我的路是从这里开始的,但是这里不再是乐土.感谢曾经影响过,引导过,帮助过我的董凯,飞燕,leeco,starwing,Rockcarry,soft_wind等等等等.别了,BCCN.
2011-11-15 20:35
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 18楼 卧龙孔明
求问此题怎么写母函数?
2011-11-15 20:38
waterstar
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:5
帖 子:984
专家分:2810
注 册:2010-2-12
收藏
得分:0 
回复 18楼 卧龙孔明
没搜到数学证明的过程,有链接吗?或者直接说明一下?

冰冻三尺,非一日之寒;士别三日,不足刮目相看!
2011-11-15 20:39
快速回复:瓷砖覆盖地面问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014223 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved