当前位置: 代码迷 >> 综合 >> 【Codeforces Round #518 (Div. 2) [Thanks, Mail.Ru!] D. Array Without Local Maximums】DP+滚动数组优化
  详细解决方案

【Codeforces Round #518 (Div. 2) [Thanks, Mail.Ru!] D. Array Without Local Maximums】DP+滚动数组优化

热度:58   发布时间:2023-12-29 02:29:05.0

D. Array Without Local Maximums

题意

本来有一个n个数字的数组,数字大小从1到200本来有一个n个数字的数组,数字大小从1到200n1200
现在有些数字看不清了,但是只记得原数组有一种性质现在有些数字看不清了,但是只记得原数组有一种性质
a[2]>=a[1]a[2]>=a[1]a[2]>=a[1]
a[n?1]>=a[n]a[n-1]>=a[n]a[n?1]>=a[n]
a[i]&lt;=max(a[i?1],a[i+1])2&lt;=i&lt;=n?1a[i]&lt;=max(a[i-1],a[i+1]) \ \ \ 2&lt;=i&lt;=n-1a[i]<=max(a[i?1],a[i+1])   2<=i<=n?1

做法
对于这个数据范围,很显然就能想到dp对于这个数据范围,很显然就能想到dpdp
定义DP状态为dp[i][j][k]定义DP状态为dp[i][j][k]DPdp[i][j][k]
dp[i][j][0]表示第i个数为j而且小于前一个数的状态数dp[i][j][0] 表示第i个数为j而且小于前一个数的状态数dp[i][j][0]ij
dp[i][j][1]表示第i个数为j而且等于前一个数的状态数dp[i][j][1] 表示第i个数为j而且等于前一个数的状态数dp[i][j][1]ij
dp[i][j][2]表示第i个数为j而且大于前一个数的状态数dp[i][j][2] 表示第i个数为j而且大于前一个数的状态数dp[i][j][2]ij
转移方程也很显然,只不过对于第二个位置的dp数组要特殊处理转移方程也很显然,只不过对于第二个位置的dp数组要特殊处理dp
而且需要滚动数组对dp进行前缀和优化而且需要滚动数组对dp进行前缀和优化dp

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<<x<<endl
typedef long long ll;
const ll Mod = 998244353 ;
const int maxn = 1e5+10;
ll dp[maxn][201][3];
ll a[maxn];
ll sum1[maxn],sum2[maxn];
int main()
{
    int n;scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);if(a[1]==-1){
    if(a[2]==-1){
    for(int j=1;j<=200;j++){
    dp[2][j][1]=1;dp[2][j][2]=j-1;}}else{
    dp[2][a[2]][1]=1;dp[2][a[2]][2]=a[2]-1;}}else{
    if(a[2]==-1){
    for(int j=a[1]+1;j<=200;j++){
    dp[2][j][2]=1;}dp[2][a[1]][1]=1;}else{
    if(a[1]==a[2]) dp[2][a[2]][1]=1;else if(a[1]<a[2])  dp[2][a[2]][2]=1;}}for(int j=1;j<=200;j++) sum1[j]=(sum1[j-1]+dp[2][j][0]+dp[2][j][1]+dp[2][j][2])%Mod;for(int j=200;j>=1;j--) sum2[j]=(sum2[j+1]+dp[2][j][0]+dp[2][j][1])%Mod;for(int i=3;i<=n;i++){
    if(a[i]!=-1){
    dp[i][a[i]][0]=sum2[a[i]+1];dp[i][a[i]][1]=(dp[i-1][a[i]][0]+dp[i-1][a[i]][1]+dp[i-1][a[i]][2])%Mod;dp[i][a[i]][2]=sum1[a[i]-1];}else{
    for(int j=1;j<=200;j++){
    dp[i][j][0]=(dp[i][j][0]+sum2[j+1])%Mod;dp[i][j][1]=(dp[i-1][j][0]+dp[i-1][j][1]+dp[i-1][j][2])%Mod;dp[i][j][2]=(dp[i][j][2]+sum1[j-1])%Mod;}}for(int j=1;j<=200;j++) sum1[j]=(sum1[j-1]+dp[i][j][0]+dp[i][j][1]+dp[i][j][2])%Mod;for(int j=200;j>=1;j--) sum2[j]=(sum2[j+1]+dp[i][j][0]+dp[i][j][1])%Mod;}ll ans=0;for(int i=1;i<=200;i++){
    ans=(ans+dp[n][i][0]+dp[n][i][1])%Mod;}printf("%lld\n",ans);return 0;
}
  相关解决方案