zoukankan      html  css  js  c++  java
  • codeforces Array Without Local Maximums

    题目描述

    题解

    考虑dp,设f[i][j][0/1]表示前i个数,第i个数为j,第i-1个数小于/大于等于j的方案数

    考虑转移,假设第i个数选j,第i-1个数选k,则
    1.$k>j$ $f[i-1][k][1]=>f[i-1][j][1]$
    2.$k=j$ $f[i-1][k][0]+f[i-1][k][1]=>f[i-1][j][1]$
    3.$k<j$ $f[i-1][k][0]+f[i-1][k][1]=>f[i-1][j][0]$

    前缀和优化即可,效率: $O(200n)$

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+5,P=998244353;
    int n,f[205][2],pr[205][2],sf[205][2],a[N],s;
    int X(int x){return x>=P?x-P:x;}
    int main(){
        cin>>n;
        for (int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        if (~a[1]) f[a[1]][0]=1;
        else for (int i=1;i<=200;i++) f[i][0]=1;
        for (int i=2;i<=n;i++){
            for (int j=1;j<=200;j++)
                pr[j][0]=X(pr[j-1][0]+f[j][0]),
                pr[j][1]=X(pr[j-1][1]+f[j][1]);
            for (int j=200;j;j--)
                sf[j][0]=X(sf[j+1][0]+f[j][0]),
                sf[j][1]=X(sf[j+1][1]+f[j][1]);
            for (int j=1;j<=200;j++){
                f[j][0]=f[j][1]=0;
                if ((~a[i]) && a[i]!=j) continue;
                f[j][1]=X(pr[j][0]-pr[j-1][0]+P);
                f[j][1]=X(f[j][1]+X(pr[j][1]-pr[j-1][1]+P));
                f[j][1]=X(f[j][1]+sf[j+1][1]);
                f[j][0]=X(pr[j-1][0]+pr[j-1][1]);
            }
        }
        for (int i=1;i<=200;i++)
            s=X(s+f[i][1]);
        cout<<s<<endl;return 0;
    }
  • 相关阅读:
    必备单词
    Vim
    Linux基础
    python链表操作详解
    冒泡和快速排序
    学员练车选课系统
    面试题
    获取resp:heads:content-disposition的filename
    记录springBoot启动报错(无脑型)
    springBoot+Vue搭建新项目(1)
  • 原文地址:https://www.cnblogs.com/xjqxjq/p/12305657.html
Copyright © 2011-2022 走看看