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;
}