codeforces 518A. Array Without Local Maximums

Ivan unexpectedly saw a present from one of his previous birthdays. It is array of n 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
ai≤max(ai−1,ai+1) (for all i 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 n(2≤n≤105) — size of the array.
Second line of input contains n integers ai — elements of array.
Either ai=−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 1 and 200.


暴力是永远不可能的,搜索不行上DP。
对于一可行序列,只考虑最后三位,共有如下排列方式
排列顺序
综合整理,设计问题规模由1合并至长度len的DP算法。

记DP数组DP[i][num][s]。
其中 i 为当前序列的长度,num 为当前序列的最后一位,s 为状态编号。数组中记录符合题意的排列数。
情况示意图
现考虑对长度为 i 的序列,在第 i 位( i>1 )的任意数字 n (1<=n<=200)。
根据题意题意及可行序列最后三位的所有可能排列情况可知:
dp[i][n][0]+=sum( i star 1 to n-1):(dp[i-1][i][0]+dp[i-1][i][1]);

dp[i][n][1]+=sum( i star n+1 to 200):(dp[i-1][i][1])+(dp[i- 1][n][1]+dp[i-1][n][0]);

通过这个递推关系就能确定对于第 i 位(i>1)上的所有情况。

再考虑初始化情况。假定在给定序列前有一位记为第0位,值为 0 .这样使第一位符合DP数组的含义。根据DP数组含义可知第1位不可能比第0位大。
当第1位确定为num时,则DP[1][num][0]=1;
当第1位不确定时,则(i star 1 to 200)DP[1][i][0]=1;

注意结果较大,应使用long long 数据类型。


#include <stdio.h>
#include <cstring>
#include <climits>
#include <algorithm>
#define mod 998244353
using namespace std;

int store[100005];
long long dp[100005][202][2];
int main(){
    int len;
    scanf("%d",&len);
    for(int i=1;i<=len;i++)
        scanf("%d",&store[i]);
    memset(dp,0,sizeof(dp));
    if(store[1]!=-1){
        dp[1][store[1]][0]=1;
    }else{
        for(int i=1;i<=200;i++){
            dp[1][i][0]=1;
            dp[1][i][1]=0;
        }
    }
    for(int i=2;i<=len;i++){
        if(store[i]==-1){
            /*
            for(int c=1;c<=200;c++){
                for(int k=1;k<c;k++)
                    dp[i][c][0]=(dp[i][c][0]+dp[i-1][k][1]+dp[i-1][k][0])%mod;
                for(int k=c+1;k<=200;k++)
                    dp[i][c][1]=(dp[i][c][1]+dp[i][k][1])%mod;
                dp[i][c][1]=(dp[i][c][1]+dp[i-1][c][1]+dp[i-1][c][0])%mod;
            }
            */
            dp[i][1][0]=0;
            for(int c=2;c<=200;c++)
                dp[i][c][0]=(dp[i][c][0]+dp[i][c-1][0]+dp[i-1][c-1][0]+dp[i-1][c-1][1])%mod;
            dp[i][200][1]=0;
            for(int c=199;c>=1;c--){
                dp[i][c][1]=(dp[i][c][1]+dp[i][c+1][1]+dp[i-1][c+1][1])%mod;
            }
            for(int c=1;c<=200;c++)
                dp[i][c][1]=(dp[i][c][1]+dp[i-1][c][1]+dp[i-1][c][0])%mod;
        }else{
            int num=store[i];
            for(int j=1;j<num;j++)
                dp[i][num][0]=(dp[i][num][0]+dp[i-1][j][0]+dp[i-1][j][1])%mod;
            for(int j=num+1;j<=200;j++)
                dp[i][num][1]=(dp[i][num][1]+dp[i-1][j][1])%mod;
            dp[i][num][1]=(dp[i][num][1]+dp[i-1][num][0]+dp[i-1][num][1])%mod;
        }
    }
    long long ans=0;
    for(int i=1;i<=200;i++)
        ans=(ans+dp[len][i][1])%mod;
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/white_156/article/details/83421537