题目传送门

  题目大意:给出一个长度为n的数组,这个数组有的数是给出的,有的数是固定的,且范围都在[1,200]之间,要求这个数组中,每一个数字都小于等于 前后两个数字的最大值,求方案数mod p。

  思路:一眼看出是个dp,但是不太擅长这个,看了大佬的题解,又加上了一些自己的思考。

  由于这个数组每一个元素都是前后相关的,所以应该是个线性dp的东西,既然是线性的,我们就先考虑每一个元素和前面一个元素的关系(没法往后看,因为后面的元素都没有得到),将当前这个数字和前面的数字进行比较,会得到“>”“=”“<”这样三种状态,如果我们用dp[ i ][ x ][ flag ]表示第i个位子填x,和前面元素关系是flag,flag有0,1,2三种状态,分别表示大于,等于,小于。我们可以得到

  dp[i+1][ y ][0]=dp[i][ x ][0,1,2]   (x<y)

  dp[i+1][ y ][1]=dp[i][ y ][0,1,2]   (x==y)

  dp[i+1][ y ][2]=dp[i][ x ][1,2]      (x>y)

  而对于第一个位置来说,显然不会小于等于前一个,否则第二个格子就可以随便填了,所以第一个格子只有状态为0,值才等于1.

  得到了这个递推式就可以dp了,需要注意的是,对于第一条递推式,由于我要累加所有满足(x<y)的x,很多人可能会枚举x,但事实上我们只需要注意一下x的遍历顺序,把每次的值都累计在一个sum里面就可以了。

  但是这道题我们更应该思考的是,为什么要这样dp?

  我的理解是,由于每个元素的限制条件其实是当前元素和前后元素的大小关系,也就是说合法性和大小关系有关,所以就对大小关系进行拆解(其实我觉得拆成<=和>就够了)。而我保证了当前格子的情况都是合法的情况,不断递推,递推到最后一个格子时,最后一个格子的绝对合法情况就是答案,即dp[n][x][1]+dp[n][x][2];

//#pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<stdlib.h>
//#include<unordered_map>
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)|1
#define CLR(a,b) memset(a,b,sizeof(a))
#define mkp(a,b) make_pair(a,b)
typedef long long ll;
using namespace std;
inline int read(){
int x=,f=;
char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;}
const int maxn=1e5+;
ll p=;
ll dp[maxn][][];
int a[maxn],n;
int main(){
cin>>n;
for(int i=;i<=n;i++)
{
a[i]=read();
}
for(int x=;x<=;x++)
{
if(a[]!=-&&a[]!=x)dp[][x][]=dp[][x][]=dp[][x][]=;
else dp[][x][]=,dp[][x][]=dp[][x][]=;
}
ll sum;
for(int i=;i<=n;i++)
{
sum=;
for(int x=;x<=;x++)
{
if(a[i]!=-&&a[i]!=x)dp[i][x][]=;
else dp[i][x][]=sum;
sum=(sum+dp[i-][x][]+dp[i-][x][]+dp[i-][x][])%p;
}
for(int x=;x<=;x++)
{
if(a[i]!=-&&a[i]!=x)dp[i][x][]=;
else dp[i][x][]=(dp[i-][x][]+dp[i-][x][]+dp[i-][x][])%p;
}
sum=;
for(int x=;x>;x--)
{
if(a[i]!=-&&a[i]!=x)dp[i][x][]=;
else dp[i][x][]=sum;
sum=(sum+dp[i-][x][]+dp[i-][x][])%p;
}
}
sum=;
for(int i=;i<=;i++){
sum=(sum+dp[n][i][]+dp[n][i][])%p;
}
printf("%lld\n",sum);
}

codeforces 1068d Array Without Local Maximums dp的更多相关文章

  1. 【非原创】codeforces - 1067A Array Without Local Maximums【dp】

    学习博客:戳这里 附本人代码: 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 co ...

  2. 【计数dp】Array Without Local Maximums

    参考博客:[CF1068D]Array Without Local Maximums(计数DP) [题意] n<=1e5 dp[i][j][k]表示当前第i个数字为j,第i-1个数字与第i个之间 ...

  3. 【CF1068D】Array Without Local Maximums(计数DP)

    题意: n<=1e5 思路:卡内存 dp[i][j][k]表示当前第i个数字为j,第i-1个数字与第i个之间大小关系为k的方案数(a[i-1]<a[i],=,>) 转移时使用前缀和和 ...

  4. 「题解报告」CF1067A Array Without Local Maximums

    大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解 原题传送门 动态规划三部曲:确定状态,转移方程,初始状态和答案. --神 ...

  5. [Codeforces 865C]Gotta Go Fast(期望dp+二分答案)

    [Codeforces 865C]Gotta Go Fast(期望dp+二分答案) 题面 一个游戏一共有n个关卡,对于第i关,用a[i]时间通过的概率为p[i],用b[i]通过的时间为1-p[i],每 ...

  6. [CodeForces - 1225E]Rock Is Push 【dp】【前缀和】

    [CodeForces - 1225E]Rock Is Push [dp][前缀和] 标签:题解 codeforces题解 dp 前缀和 题目描述 Time limit 2000 ms Memory ...

  7. [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)

    [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...

  8. Codeforces 57C Array dp暴力找到规律

    主题链接:点击打开链接 的非增量程序首先,计算, 如果不增加的节目数量x, 非减少一些方案是x 答案就是 2*x - n 仅仅需求得x就可以. 能够先写个n3的dp,然后发现规律是 C(n-1, 2* ...

  9. codeforces Diagrams & Tableaux1 (状压DP)

    http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...

随机推荐

  1. SpringBoot26 RestTemplate、WebClient

    1 RestTemplate RestTemplate是在客户端访问 Restful 服务的一个核心类:RestTemplate通过提供回调方法和允许配置信息转换器来实现个性化定制RestTempla ...

  2. vmware workstation + kvm 部署

    1.物理机BIOS设置里开启虚拟化功能 2.vm里面开启一下两个功能 3.找到存放该虚拟机的dir,找到以.vmx结尾的文件,增加一行 apic.xapic.enabled = "FALSE ...

  3. Web服务器父与子 Apache和Tomcat区别(转)

    From http://developer.51cto.com/art/201007/210894.htm 熟悉三国的朋友都知道曹操,曹操有二十五个儿子,其中最得曹操宠爱的是曹丕.曹植.曹彰三个,曹丕 ...

  4. c语言实践 打印字母三角形

    效果如下: 我是怎么想的: 总共需要打印6行字母,那么就需要一个循环来控制打印第几行,大概代码如下: for(int i=0;i<6;i++) { } 每行都会打印字母,而且循环越往后,需要打印 ...

  5. ZIP压缩格式与RAR压缩格式

    早已习惯了安装系统之后必须安装winrar,压缩文件也已经习惯了rar格式,这种习惯的力量真的挺可怕的.在工作中你的同事可能没有安装winrar,或者他们不喜欢安装盗版软件,这时候你给他们发送过去的是 ...

  6. React项目中的registerServiceWorker的作用

    在公司的React前端项目中,发现有一个registerServiceWorker.js文件, 很久都没弄明白这个文件是干什么用的,查询了一些资料后,了解了一些 service worker是在后台运 ...

  7. Daubechies Wavelet

    The Daubechies wavelets, based on the work of Ingrid Daubechies, are a family of orthogonal wavelets ...

  8. 编写高质量代码改善C#程序的157个建议——建议39:了解委托的实质

    建议39:了解委托的实质 理解C#中的委托需要把握两个要点: 1)委托是方法指针. 2)委托是一个类,当对其进行实例化的时候,要将引用方法作为它的构造方法的参数. 设想这样一个场景:在点对点文件传输过 ...

  9. repo相关命令

    1.repo start <topic_name> 开启一个新的主题,其实就是每个Project都新建一个分支. repo start newbranchname . 创建新的branch ...

  10. react-native-echarts构建的图表出现滚动条并且可以滑动的问题

    前段时间做echarts饼状图,按照官方提供的写法完成以后图表可以出来,但是虚拟机上演示出现了滚动条,并且拖动时就会出现空白,双击会缩小像这样       参考GitHub上给出的方法修改成功: no ...