题目传送门

  题目大意:给出一个长度为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. 824. Goat Latin山羊拉丁文

    [抄题]: A sentence S is given, composed of words separated by spaces. Each word consists of lowercase ...

  2. PyV8在服务端运行自动崩溃问题

    近来想在服务端架设WSGI + PyV8去自动解析JavaScript代码,然后返回解析后的数据给客户端.但是发现,在nginx配置后,客户端一请求,服务端的python脚本自动崩溃. 见代码: de ...

  3. VIVADO生成MCS

    tcl console里面执行 write_cfgmem -format mcs -interface spix4 -size 128 -loadbit "up 0 E:/x.bit&quo ...

  4. Training Very Deep Networks

    Rupesh Kumar SrivastavaKlaus Greff ̈J urgenSchmidhuberThe Swiss AI Lab IDSIA / USI / SUPSI{rupesh, k ...

  5. 编写高质量代码改善C#程序的157个建议——建议45:为泛型类型参数指定逆变

    建议45:为泛型类型参数指定逆变 逆变是指方法的参数可以是委托或者泛型接口的参数类型的基类.FCL4.0中支持逆变的常用委托有: Func<int T,out TResult> Predi ...

  6. 类的 where T : class 泛型类型约束

    where T : struct | T必须是一个结构类型where T : class T必须是一个类(class)类型where T : new() | T必须要有一个无参构造函数where T ...

  7. attachEvent 与 addEventListener 的监听

    说到 attachEvent 与 addEventListener 的事件必然会提到  浏览器的判断,因为attachEvent只适用于于IE 先来看看常用的浏览器的判断 //判断浏览器类型 if(n ...

  8. 【转】快速开发移动医疗App!开源框架mHealthDroid

    原文地址:http://www.csdn.net/article/2014-12-12/2823096-mHealhDroid mHealthDroid是一款开源的移动框架,主要用于帮助开发者快速而又 ...

  9. 搜索引擎Hoot的源码阅读(提供源码)

    开门见山,最近阅读了一下一款开源引擎的源码,受益良多(学到了一些套路).外加好久没有写博客了(沉迷吃鸡,沉迷想念姑娘),特别开一篇.Hoot 的源码地址, 原理介绍地址.外加我看过之后的注释版本,当然 ...

  10. WinForm中ListBox的使用

    获取选中数据:listbox.SelectedItem as XXX 重绘每一行item DrawMode设置为DrawMode.OwnerDrawVariable 然后实现DrawItem(obje ...