题目传送门

  题目大意:给出一个长度为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. 启动dhcp出错:No subnet declaration for eth0 (192.168.0.1

    XUbuntu 8.04 i386.装了dhcp3-server.使用 sudo /etc/init.d/dhcp3-server start 出错:Apr 30 14:24:03 s dhcpd: ...

  2. MySQL - pt-query-digest的下载与使用

    对于脚本文件,是可以执行的,我们不用安装.所以,但是这个脚本文件没有执行的权限,所以,我们首先赋予这个脚本文件的可执行的权限. 再次查看文件的信息后. 已经有了执行的权限了. 运行脚本的时候,可要注意 ...

  3. ubuntu 64 14.04 共享文件夹问题

    转自http://blog.csdn.net/gongyuan073/article/details/46604233 原文链接: http://blog.csdn.NET/chinley/artic ...

  4. Django cache

    Django中使用redis 方式一: utils文件夹下,建立redis_pool.py import redis POOL = redis.ConnectionPool(host='127.0.0 ...

  5. 利用URL重写实现Session跟踪

    Servlet规范中引入了一种补充的会话管理机制,它允许不支持Cookie的浏览器也可以与WEB服务器保持连续的会话.这种补充机制要求在响应消息的实体内容中必须包含下一次请求的超链接,并将会话标识号作 ...

  6. 如何将一个用utf-8编码的文本用java程序转换成ANSI编码的文本

    jdk有一个关于UTF-8的bug所以加了一句 br.skip(1); bugID: http://bugs.java.com/view_bug.do?bug_id=4508058 public st ...

  7. Linux下ffmpeg安装与开发配置

    Linux下ffmpeg安装与开发配置   1. ffmpeg安装 安装环境: ubuntu 12.04 (1)删除已安装的文件,避免冲突 sudo apt-get remove ffmpeg x26 ...

  8. Extjs Hello extjs

    <html > <head runat="server"> <title></title> <link rel="s ...

  9. WndProc

    主要用在拦截并处理系统消息和自定义消息. form窗体的一个重载方法. protected override void WndProc(ref Message m) { //拦截窗体最小化按钮消息 i ...

  10. Java集合类总结 (三)

    HashSet类 关于HashMap的实现细节 HashMap是用LinkedList实现的,每个list被称为一个桶(bucket),在hashmap中要查找一个元素,首先对传入的key进行散列,并 ...