【DP求方案数】 Codeforces Round #518 (Div. 2) [Thanks, Mail.Ru!] D. Array Without Local Maximums

http://codeforces.com/contest/1068/problem/D

D. Array Without Local Maximums

Ivan unexpectedly saw a present from one of his previous birthdays. It is array of nn numbers from 1 to 200. Array is old and some numbers are hard to read. Ivan remembers that for all elements at least one of its neighbours ls not less than it, more formally:

a1≤a2,

an≤an−1 and

ai≤max(ai−1,ai+1) for all ii from 2 to n−1.

Ivan does not remember the array and asks to find the number of ways to restore it. Restored elements also should be integers from 1 to 200. Since the number of ways can be big, print it modulo 998244353.

Input

First line of input contains one integer nn (2≤n≤1e5) — size of the array.

Second line of input contains nn integers aiai — elements of array. Either ai=−1ai=−1 or 1≤ai≤200. ai=−1 means that i-th element can't be read.

Output

Print number of ways to restore the array modulo 998244353.

Examples

input

3
1 -1 2

output

1

input

2
-1 -1

output

200

Note

In the first example, only possible value of a2 is 2.

In the second example, a1=a2 so there are 200 different values because all restored elements should be integers between 1and 200.

题意:给定一个长度为 n(n≤1e5)的数组 a,a[i] 的值域为 1 到 200,且每个数的旁边必须有一个不小于它的数。而有些数字被擦掉了(-1),现在问共有多少种可行的填充方案。

题解:

考虑 dp[i][x][0,1,2]的表示的状态为已经确定了第 i个数字为 x,而 0,1,2 分别表示第 i−1个数 w 是小于、等于或大于x。其存储的值是其状态下的方案数。

状态转移方程

dp[i+1][y][0]=∑x=1——y−1dp[i][x][0,1,2]

dp[i+1][y][1]=dp[i][y][0,1,2]

dp[i+1][y][2]=∑x=y+1——200dp[i][x][1,2]

边界条件,考虑到第 1 个数左边是空的,相当于左边是一个更小的数,因此有(依然是建立在第一位能填入 x 的前提下):

dp[1][x][0]=1

dp[1][x][1]=0

dp[1][x][2]=0

#include 
#define ll long long
using namespace std;
const int maxn=1e5+10;
int a[maxn];
const ll mod=998244353 ;
ll dp[maxn][205][3];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);

    for(int i=1;i<=200;i++)
    {
        if(a[1]!=-1&&a[1]!=i)
            dp[1][i][0]=dp[1][i][1]=dp[1][i][2]=0;
        else dp[1][i][0]=1,dp[1][i][1]=dp[1][i][2]=0;
    }

    ll sum;
    for(int i=2;i<=n;i++)
    {
        sum=0;
        for(int y=1;y<=200;y++)
        {
            if(a[i]!=-1&&a[i]!=y) dp[i][y][0]=0;
            else dp[i][y][0]=sum;
            sum=(sum+dp[i-1][y][0]+dp[i-1][y][1]+dp[i-1][y][2])%mod;
        }

        for(int y=1;y<=200;y++)
        {
            if(a[i]!=-1&&a[i]!=y) dp[i][y][1]=0;
            else dp[i][y][1]=(dp[i-1][y][0]+dp[i-1][y][1]+dp[i-1][y][2])%mod;
        }

        sum=0;
        for(int y=200;y>=1;y--)
        {
            if(a[i]!=-1&&a[i]!=y) dp[i][y][2]=0;
            else dp[i][y][2]=sum;
            sum=(sum+dp[i-1][y][1]+dp[i-1][y][2])%mod;
        }
    }

    sum=0;
    for(int i=1;i<=200;i++)
    {
        sum=(sum+dp[n][i][1]+dp[n][i][2])%mod;
    }
    printf("%lld\n",sum);


    return 0;
}

 

你可能感兴趣的:(DP)