smoj1710:砖块II (dp套dp)
来源:互联网 发布:淘宝物流评价怎么修改 编辑:程序博客网 时间:2024/05/16 04:08
砖块II
题目描述
有K种不同规则的长方体砖块,长宽高分别是:1×1×1、2×1×1、3×1×1…,K×1×1.还给出一个W×1×1的地基,如下图所示,W=9, k=3,下面的是地基:
现在你要在地基上堆放砖块,必须满足如下的规则:
1、 砖块只能横放,不能竖放。
2、 砖块必须放置在整数位置,且不能越出地基。
3、 砖块任何部分的正下方都必须要有其他砖块或者是地基。
例如:下图是不合法的放置方式,有4个不合法的地方:
我们定义一种堆放砖块方案的高度height:它是指该方案中最高的砖块是第几层,其中地基是第0层,例如(图二)的高度是3。
我们定义不同的堆放方案:例如有两种堆放方案A和B,只要满足两个条件之一,方案A和方案B就是不同的方案:
1、 在某个位置方案A有砖块而方案B在该位置没有砖块,或者方案B有砖块而方案A没有。
2、 在某个位置方案A和方案B都有砖块,但是它们不是同一种规格的砖块。
给定地基的长度W,和地砖的最大长度K,你的任务是计算有多少种不同的堆放砖块的方案,你的堆放砖块方案的高度height不能超过给定的H。答案模1000000007。
例如:下图是W=3, k=3, H=2的所有合法方案:
输入格式 1710.in
多组测试数据。
第一行,一个整数G,表示有G组测试数据。1 <= G <=3。
每组测试数据格式如下:
一行,三个整数W、H、K 。1 <= W, H <= 50。 1 <= K <= W
输出格式 1710.out
共G行,每行一个整数。
输入样例 1710.in
3
3 1 3
3 2 3
10 10 3
输出样例 1710.out
13
83
288535435
题目分析:这题其实不算难,然而我考试的时候还是没想出来。感觉自己数据结构题做多了,思维好像有点退化……。我们先看原问题:地基长度为W,高度限制为H,记为f(W,H)。然后我们考虑一层一层地铺。对于最下面一层,如果全部铺满,问题就变成了f(W,H-1)。我们求出f(W,H-1)后并不是直接加进f(W,H)的答案中,因为下面这一层长度为W的连续一段,又有很多种铺法,我们记为dp[W]。根据乘法原理,我们将f(W,H-1)*dp[W]加进f(W,H)中,而我们知道dp[W]又可以通过预处理一个DP来求。那么假设最下面一层没有铺满呢?那么这一层必定有一个最右边的空格子,假设它在第i个位置。由于他已经是最右的空格子,故它右边一定是连续的一段。类似上面的推导过程,右边可能的铺法有f(W-i,H-1)*dp[W-i]种,而左边就转化为了子问题f(i-1,H)。我们枚举i,然后把f(i-1,H)*f(W-i,H-1)*dp[W-i]加进f(W,H)里即可。
在这里要注意一下边界的处理:由于我们用的是乘法原理,所以dp[0],f[i][0],f[0][i]都要初始化为1。
CODE:
#include<iostream>#include<string>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<stdio.h>#include<algorithm>using namespace std;const int maxn=55;const long long M=1000000007;typedef long long LL;LL dp[maxn];LL f[maxn][maxn];int G,W,H,K;int main(){freopen("b.in","r",stdin);freopen("b.out","w",stdout);scanf("%d",&G);while (G--){scanf("%d%d%d",&W,&H,&K);memset(dp,0,sizeof(dp));memset(f,0,sizeof(f));dp[0]=1;for (int i=1; i<=W; i++){dp[i]=0;for (int j=1; j<=min(i,K); j++) dp[i]=(dp[i]+dp[i-j])%M;}for (int i=0; i<=W; i++) f[0][i]=1;for (int i=1; i<=H; i++) f[i][0]=1;for (int i=1; i<=H; i++)for (int len=1; len<=W; len++){f[i][len]=f[i-1][len]*dp[len]%M;for (int j=1; j<=len; j++)f[i][len]=(f[i][len]+f[i-1][j-1]*f[i][len-j]%M*dp[j-1]%M)%M;}cout<<f[H][W]<<endl;}return 0;}
- smoj1710:砖块II (dp套dp)
- [SMOJ1710]砖块II
- 敲砖块(dp )
- [noip模拟赛]敲砖块(dp)
- luoguP1437 [HNOI2004]敲砖块(dp)
- 【codevs1257】打砖块 DP
- hdu4899 dp套dp
- 神奇DP [HNOI2004] 打砖块
- bzoj1296(dp套背包dp)
- bzoj 3864 dp套dp
- [DP套DP] HDU5079: Square
- poj 2411 Mondriaan's Dream 铺砖块(状压dp)
- 2017网易春招 堆砖块(DP)
- HDU 4899 Hero meet devil(DP套DP)
- poj 2411 状态压缩DP 铺砖块
- 状态压缩dp poj2411 1*2砖块
- DP——Luogu1437 [HNOI2004]敲砖块
- 游船问题II(DP)
- NOIP复习范围--思维导图
- 为Python安装机器学习编程库
- 友盟:微信,QQ,新浪微博第三方登录
- THUWC2017 bipartite
- Android 自定义ScrollView嵌套滚动兼容,监听滑动状态:顶部、底部、停止、滑动中
- smoj1710:砖块II (dp套dp)
- 为php设置系统变量、环境变量
- Android 长LOG打印不全解决办法一
- DataFrame.mean()函数
- std::hash实现太简单分布不匀
- H5响应式设计可以为你网站带来什么?
- mac的java环境配置
- POJ 3126 Prime Path
- 【C#/WPF】Image图片的Transform变换:平移、缩放、旋转