【gmoj】【NOIP2013模拟11.4A组】 【DP】 积木


解题思路
考试的时候就很懵
-1的积木高度有很多种啊
好像模拟不出来
事实上,确实如此
-1的积木高度有很多种
而每一高度都由它前一个+1,-1,或不变的方案和转移过来
当然如果它为0,就不存在-1的情况,所以为0时要先处理
代码
#include<iostream>
#include<cstdio>
using namespace std;
const long long int mo=1000000007;
long long n,h[20010],d[5][10010];
int mod(int x) //求出最大的高度
{
if (x<=n/2) return x-1;
return n-x;
}
int main()
{
freopen("brick.in","r",stdin);
freopen("brick.out","w",stdout);
scanf("%lld",&n);
for (int i=1;i<=n;i++)
scanf("%lld",&h[i]);
if (h[1]>0)
{
printf("0");
return 0;
}
d[1][0]=1; //赋初值
for (int i=2;i<=n;i++)
{
int i1=i%2,i2=(i-1)%2; //滚动数组
for (int j=0;j<=mod(i);j++) d[i1][j]=0; //清0
if (h[i]==-1) //-1时高度不确定,每种高度都要做
{
d[i1][0]=(d[i2][0]+d[i2][1])%mo;
for (int j=1;j<=mod(i);j++)
d[i1][j]=((d[i2][j]+d[i2][j-1]%mo)+d[i2][j+1])%mo;
}
else if (h[i]==0) //高度已确定,直接从它上一状态转移
d[i1][0]=(d[i2][0]+d[i2][1])%mo;
else d[i1][h[i]]=((d[i2][h[i]]+d[i2][h[i]-1])%mo+d[i2] [h[i]+1])%mo;
}
printf("%lld",d[n%2][0]);
return 0;
}

本文详细解析了NOIP2013模拟赛中的一道积木堆叠问题,通过动态规划的方法解决了不同积木高度变化带来的复杂度问题,并给出了完整的C++实现代码。
258

被折叠的 条评论
为什么被折叠?



