codeforces1068——D.Array Without Local Maximums(计数DP+前缀和优化)

简介: codeforces1068——D.Array Without Local Maximums(计数DP+前缀和优化)

原题链接

题意:

给定一个序列,a[i]==-1表示该位无元素。现在要你填充这个序列使得a[i]<=max(a[i+1],a[i-1]),a[0]=a[n+1]=0

(最后一句可以这样理解)

1<=a[i]<=200.求方案数

思路:

计数DP,推了好久,还没想到前缀和优化。

首先是状态表示,因为a[i]的范围只有200,我们不妨来枚举填1~200的每一种情况:dp[i][j][k]表示第i个数填j时并且和第i-1个数的关系为k的方案数,当然这肯定是只有需要填数时才可以转移。

接下来是状态转移,我们考虑a[i-1]的合法性来进行转移:

1.当k=0时,表示a[i]>a[i-1],这时候第i-1个数只能从[1,j-1]里选择,因为a[i-1]<a[i]一定成立了,所以a[i-1]和a[i-2]的关系可以是大于,小于和等于。

2.当k=1时,表示a[i]==a[i-1],这时候只能从dp[i-1][j]转移过来了,同时对于a[i-2]来说,k=0/1/2都成立。

3.当k=2时,表示a[i]<a[i-1],这时候第i-1个数只能从[j+1,200]里选了,同时因为a[i-1]>a[i],所以a[i-1]<=a[i-2]必须满足,即k=1/2。

关于初始化,如果a[1]=-1的话,说明该位可以填充,就dp[1][j][0]=1,我们可以理解为a[0]=0,所以第1个数填j(1<=j<=200)的方案数就是1;如果a[1]原本有数的话,就dp[1][a[1][0]=1.

最后是优化: 上面算法的复杂度是O(200 *200 *n),我们可以对情况1和情况3用前缀和优化。

代码:

const int maxn=1e5+100;
///a[i]<=a[i-1]
///dp[i][j][k]表示第i个数选j和第i-1个数的关系是k的方案数
///k==0 a[i]>a[i-1]  dp[i-1][1~j-1][0/1/2]
///k==1 a[i]==a[i-1] dp[i-1][j][0/1/2]
///k==2 a[i]<a[i-1]  dp[i-1][j+1~200][1/2]
ll dp[maxn][205][3];
ll a[maxn],n;
int main()
{
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    if(a[1]!=-1) dp[1][a[1]][0]=1;///该位无需填充
    else///该位需要填充
        for(int i=1;i<=200;i++) dp[1][i][0]=1;
    for(int i=2;i<=n;i++){///枚举当前填充到第几个数了
        ll sum=0;
        for(int j=1;j<=200;j++){
            if(a[i]==-1||a[i]==j) dp[i][j][0]=sum;///可以填充或是该位正好为枚举的数
            sum=(sum+dp[i-1][j][0]+dp[i-1][j][1]+dp[i-1][j][2])%mod;
        }
        sum=0;
        for(int j=1;j<=200;j++){
            if(a[i]==-1||a[i]==j)
                dp[i][j][1]=(dp[i-1][j][0]+dp[i-1][j][1]+dp[i-1][j][2])%mod;
        }
        for(int j=200;j;j--){
            if(a[i]==-1||a[i]==j) dp[i][j][2]=sum;
            sum=(sum+dp[i-1][j][1]+dp[i-1][j][2])%mod;
        }
    }
    ll res=0;
    for(int i=1;i<=200;i++)
        res=(res+dp[n][i][1]+dp[n][i][2])%mod;
    out(res);
    return 0;
}
目录
相关文章
|
JavaScript
ES6对String字符串、Array数组、Number数字、Object对象 类型做了哪些升级优化
ES6对String字符串、Array数组、Number数字、Object对象 类型做了哪些升级优化
110 0
|
6月前
|
Python
使用array()函数创建数组
使用array()函数创建数组。
131 3
|
6月前
|
JavaScript 前端开发
总结TypeScript 的一些知识点:TypeScript Array(数组)(下)
一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array)。
|
1月前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
1月前
|
存储 Java
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
|
1月前
|
存储 JavaScript 前端开发
JavaScript Array(数组) 对象
JavaScript Array(数组) 对象
27 3
|
1月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
|
2月前
|
Go
Golang语言之数组(array)快速入门篇
这篇文章是关于Go语言中数组的详细教程,包括数组的定义、遍历、注意事项、多维数组的使用以及相关练习题。
34 5
|
3月前
|
Python
PyCharm View as Array 查看数组
PyCharm View as Array 查看数组
86 1
|
4月前
|
索引

热门文章

最新文章

下一篇
无影云桌面