JEDAN

考古学蓁蓁在研究某一古代文明时,发现有一种梯形建筑,简单地说是由 N 个不同高低
第 4 页冲刺 NOI2020 模拟试题
长沙市一中
的柱子排成一列组成的(柱子高度可以为零)

这种建筑可以看成是按如下规划生成:
(1) 开始时所有柱子高度为 0.
(2) 取一段高度相同的相邻的几个柱子,把这段柱子的高度增加 1(但这段的两端:第一
个和最后一个柱子不变)
(3) 可以重复上当步骤(2)

现在找到一个这样的古代遗址,可惜中间的一些柱子被秦朝时的陈-吴起义破坏了,蓁蓁想
还原这个建筑,但可能有多种可能性,现请你帮助计算出有多少种可能的还原方案。
输入:
第一行一个整数 N(1 ≤ N ≤ 10 000),表示柱子的个数。
第二行 N 个整数 hi (-1 ≤ hi ≤ 10 000 ),如果柱子高度是-1 表示它已经被破坏了。
输出:
一个整数:可能的方案数 模(mod) 1 000 000 007.
样例:
input

-1 2 -1

out 

0

input

-1 -1 -1

output 

2

input

6 -1 -1 -1 2 -1 -1

output

3

dp[i][j]表示只考虑前i个柱子的高度情况,且第i个柱子高度为j的方案数
dp[n][0]即为所求
dp[i][j]=dp[i-1][j-1]+dp[i-1][j]+dp[i-1][j+1];
多注意取模、每个位置的最大高度、转移条件等细节

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#define ll long long
#define mod 1000000007
#define R register
using namespace std;
int n,a[10000+5],dp[2][10000+5];bool cnt;int tot;
int main()
{
    freopen("jedan.in","r",stdin);
    freopen("jedan.out","w",stdout);
    cin>>n;
    for(R int i=1;i<=n;i++) cin>>a[i];
    if(a[1]>0||a[n]>0) {cout<<0<<endl;    return 0;}
    a[1]=a[n]=0;dp[1][0]=1,tot=2;
    while(tot<=n)
    {
            int up=min(n-tot+1,tot);
            for(R int i=0;i<up;i++)
                    if(a[tot]==i||a[tot]==-1)
                        dp[cnt][i]=((ll)(i?dp[!cnt][i-1]:0)+dp[!cnt][i]+dp[!cnt][i+1])%mod;
            cnt=!cnt;
            tot++;
            memset(dp[cnt],0,sizeof(dp[cnt]));
    }
    cout<<dp[!cnt][0]<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/000226wrp/p/11336249.html