「题解报告」CF1067A Array Without Local Maximums
大佬们的题解都太深奥了,直接把转移方程放出来让其他大佬们感性理解,蒟蒻们很难理解,所以我就写了一篇让像我一样的蒟蒻能看懂的题解
动态规划三部曲:确定状态,转移方程,初始状态和答案。
——神仙 @akicc
第一步 确定状态
\(f_{i,j,k}(k\in\{0,1,2\})\)表示第 \(i\) 个数选为 \(j\) 且和前一个数是小于/等于/大于(\(k=0\) 是大于,\(k=1\) 是等于,\(k=2\) 是小于)的关系时的方案数。
第二步 转移方程
把三种关系分开讨论:
- \(k=0\),比上一个大,它的方案数就是上一个数选的比它小的数的方案数和;
- \(k=1\),由于和上一个数相同,它的方案数就是上一个数的方案数和;
- \(k=2\),比上一个小,它的方案数就是上一个数选的比它大的数的方案数和,但是为了防止上一个数比相邻的数都大,我们要去掉上一个数比上上个数大的方案数。
那么我们的转移方程就是:
\(f_{i,j,0}=\sum^{j-1}_{l=1}f_{i-1,l,0}+f_{i-1,l,1}+f_{i-1,l,2}\)
\(f_{i,j,1}=f_{i-1,j,0}+f_{i-1,j,1}+f_{i-1,j,2}\)
\(f_{i,j,2}=\sum^{200}_{l=j+1}f_{i-1,l,1}+f_{i-1,l,2}\)
如果 \(a_i=-1\) 则 \(1\le j\le 200\),否则 \(j=a_i\) 。
直接求和会超时,我们可以使用前缀和优化。
第三步 初始状态和答案
如果第二个数取得比第一个数小就不符合题目要求了,而第一个数只有一种取法,所以我们让 \(f_{1,j,0}=1\),就可以让 \(f_{2,j,2}\) 取不到方案数了!
如果最后一个数比倒数第二个数大,也不符合题意,所以我们在取答案的时候不能取 \(f_{n-1,j,0}\) 。
代码
#include <bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<=b;++i)
#define for_(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
using namespace std;
const int N=1e5+10,M=998244353;
ll n,a[N],f[N][205][3],ans;
void pre(){
if(a[1]==-1)_for(i,1,200)f[1][i][0]=1;
else f[1][a[1]][0]=1;
}void dp(){
_for(i,2,n){
int s=0;
_for(j,1,200){
if(a[i]==-1||a[i]==j)f[i][j][0]=s%M,f[i][j][1]=(f[i-1][j][0]+f[i-1][j][1]+f[i-1][j][2])%M;
s=(s+f[i-1][j][0]+f[i-1][j][1]+f[i-1][j][2])%M;
}s=0;
for_(j,200,1){
if(a[i]==-1||a[i]==j)f[i][j][2]=s%M;
s=(s+f[i-1][j][1]+f[i-1][j][2])%M;
}
}
}int main(){
scanf("%lld",&n);
_for(i,1,n)scanf("%lld",&a[i]);
pre(),dp();
_for(i,1,200)ans=(ans+f[n][i][1]+f[n][i][2])%M;
printf("%lld",ans);
//system("pause");
return 0;
}
「题解报告」CF1067A Array Without Local Maximums的更多相关文章
- 「题解报告」 P3167 [CQOI2014]通配符匹配
「题解报告」 P3167 [CQOI2014]通配符匹配 思路 *和?显然无法直接匹配,但是可以发现「通配符个数不超过 \(10\) 」,那么我们可以考虑分段匹配. 我们首先把原字符串分成多个以一个通 ...
- 「题解报告」P4577 [FJOI2018]领导集团问题
题解 P4577 [FJOI2018]领导集团问题 题解区好像没有线段树上又套了二分的做法,于是就有了这片题解. 题目传送门 怀着必 WA 的决心交了两发,一不小心就过了. 题意 求一个树上最长不下降 ...
- 「题解报告」P2154 虔诚的墓主人
P2154 虔诚的墓主人 题解 原题传送门 题意 在 \(n\times m\) 一个方格上给你 \(w\) 个点,求方格里每个点正上下左右各选 \(k\) 个点的方案数. \(1 \le N, M ...
- 「题解报告」SP16185 Mining your own business
题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...
- 「题解报告」Blocks
P3503 Blocks 题解 原题传送门 思路 首先我们可以发现,若 \(a_l\) ~ \(a_r\) 的平均值大于等于 \(k\) ,则这个区间一定可以转化为都大于等于 \(k\) 的.我们就把 ...
- 「题解报告」P3354
P3354 题解 题目传送门 一道很恶心的树形dp 但是我喜欢 题目大意: 一片海旁边有一条树状的河,入海口有一个大伐木场,每条河的分叉处都有村庄.建了伐木场的村庄可以直接处理木料,否则要往下游的伐木 ...
- 「题解报告」P7301 【[USACO21JAN] Spaced Out S】
原题传送门 神奇的5分算法:直接输出样例. 20分算法 直接把每个点是否有牛的状态DFS一遍同时判断是否合法,时间复杂度约为\(O(2^{n^2})\)(因为有判断合法的剪枝所以会比这个低).而在前四 ...
- 【计数dp】Array Without Local Maximums
参考博客:[CF1068D]Array Without Local Maximums(计数DP) [题意] n<=1e5 dp[i][j][k]表示当前第i个数字为j,第i-1个数字与第i个之间 ...
- codeforces 1068d Array Without Local Maximums dp
题目传送门 题目大意:给出一个长度为n的数组,这个数组有的数是给出的,有的数是固定的,且范围都在[1,200]之间,要求这个数组中,每一个数字都小于等于 前后两个数字的最大值,求方案数mod p. 思 ...
随机推荐
- 认识弹性盒子flex
认识弹性盒子flex 来源:https://blog.xybin.top/2022/flex 1.定义弹性布局(父级上定义)display:flex; 如果说内核为webkit 的必须前面加上 -we ...
- JS:in语法
1.应用于判断对象中是否有某一个成员 var obj = { name: "lili", age:10, gender:"girl" } console.log ...
- BUUCTF-被偷走的文件
被偷走的文件 这题刚开始还以为是单纯的流量题,看流量半天也没发现什么异常. 因为是文件传输过程的,所以我们看到ftp的流量就过滤下看看即可. 在第三个包发现flag.rar存在. 一开始我觉得没啥,后 ...
- NET架构师的基本职责
NET架构师的基本职责1 职责 对本公司大健康平台提出技术研究及可行性报告; 结合需求设计高扩展性.高性能.安全.稳定.可靠的技术系统; 可以通过配置实现业务需求的变化,跟踪并研究***并应用于产品; ...
- 关于vue打包上线遇到的坑
打包上线经常会经常遇到路径找不到,页面空白,那么下面我们就解决一下. 第一步.先找到config目录的index.js 改成如上图红框标注所示 第二步.找到build下的utils.js文件 加上如上 ...
- 从位图到布隆过滤器,C#实现
前言 本文将以 C# 语言来实现一个简单的布隆过滤器,为简化说明,设计得很简单,仅供学习使用. 感谢@时总百忙之中的指导. 布隆过滤器简介 布隆过滤器(Bloom filter)是一种特殊的 Hash ...
- ansible变量引用
1. 在/etc/ansible/hosts默认文件中定义变量 [test] 192.168.163.130 #[test:vars] #key=ansible 或者 192.168.163.130 ...
- 从区划边界geojson中查询经纬度坐标对应的省市区县乡镇名称,开源Java工具,内存占用低、高性能
目录 坐标边界查询工具:AreaCity-Query-Geometry 性能测试数据 测试一:Init_StoreInWkbsFile 内存占用很低(性能受IO限制) 测试二:Init_StoreIn ...
- 校验日期格式为yyyy-MM-dd
/** * 校验时间 * * @param text * @return */ public static boolean checkTime(String text) { DateFormat fo ...
- NC15163 逆序数
NC15163 逆序数 题目 题目描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数.比如一个序列为 \ ...