[10.18模拟赛] 序列 (DP)
[10.18模拟赛] 序列
题目描述
山山有一个整数序列s1,s2,…,sn,其中1≤si≤k。
求出有多少个准确移除m个元素后不同的序列。答案模(1e9+7)
输入
输入包括几个测试用例,并且由文件结束终止。
每一个测试用例的第一行包含整数n,m和k。
第二行包含n个整数,即s1,s2,…,sn。
输出
对于每一个测试用例,输出一个表示结果的整数。
样例输入
3 2 2
1 2 1
4 2 2
1 2 1 2
样例输出
2
4
提示
\(1 ≤ n ≤ 10^5;1 ≤ m ≤ min{n - 1, 10}; 1 ≤ k ≤ 10; 1 ≤ si ≤ k;\)
n的总和不超过\(10^6.\)
Solution
其实这是牛客网暑假集训的题目
官方题解写的太飘逸~如下
预处理 Next[i][c]表示 i 之后第一个字符 c 的位置
dp[i][j]表示当时匹配到 i,删了 j 个,不同的方案数
转移时枚举下一个字符 c,转移到 dp[next[i][c],j+next[i][c]-i]
下面来讲一下蒟蒻我的理解,首先如果不考考虑删除重复元素的情况,那这道题其实还是比较水的,就是一个dp,设dp[i][j]为前i个元素删除了j个方案数
\]
这个方程还是挺好理解的吧,这道题就建立在这个方程之上
我们看这样一个序列{...,4,3,1,4,5},如果删除中间3,1,4}三个元素,集合会变成这样{...4,3,1,4,5},同样如果删除前面{4,3,1}三个元素,集合变成了这样{...4,3,1,4,5},可以看到同样的集合我们算了两遍
那么怎么减去多余的部分呢?
我们记录一下每个元素x上一次出现的位置\(pre[x]\),出现的前一段{...}我们都是会重复计算的,所以要减去\(dp[pre[x]-1][j-i+pre[x]]\)
Code
#include<bits/stdc++.h>
#define rg register
#define il inline
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)
#define lol long long
#define in(i) (i=read())
using namespace std;
const int N = 1e5+10, M=20 , mod=1e9+7;
int read() {
int ans=0,f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0',i=getchar();
return ans*=f;
}
int n,m,k;
int dp[N][M],pre[M];
int main()
{
//freopen("removal.in" , "r" , stdin);
//freopen("removal.out" , "w" , stdout);
while(scanf("%d%d%d",&n , &m , &k)!=EOF) {
memset(dp , 0 , sizeof(dp));
memset(pre , 0 , sizeof(pre));
for(int i = 0 ; i <= n ; i++) dp[i][0] = 1;
for(int i = 1 , x ; i <= n ; i++) {
in(x);
for(int j = 1 ; j <= (Min(i , m)) ; j++) {
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j])%mod;
if( pre[x] && (j >= i - pre[x]) )
(dp[i][j] -= dp[pre[x] - 1][j- i + pre[x]])%=mod;
}pre[x] = i;
}printf("%d\n",(dp[n][m]+mod)%mod);
}
}
[10.18模拟赛] 序列 (DP)的更多相关文章
- 2019.10.18模拟赛T3
题目大意: 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)>n](n\leq 10^{10})$的值. 题解: 这题貌似有n多种做法... 为 ...
- [10.12模拟赛] 老大 (二分/树的直径/树形dp)
[10.12模拟赛] 老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图), ...
- EZ 2018 06 10 NOIP2018 模拟赛(十八)
好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...
- 2018.10.17NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 +100\) 实际得分:\(100 + 100 + 60\) 辣鸡模拟赛.. 5min切掉T1,看了一下T2 T3,感觉T3会被艹爆因为太原了.. 淦了20 ...
- 4.3 省选模拟赛 序列游戏 dp
可以发现 某一段被删除后状态难以表示 也难以链接起来. 考虑暴力 有40分的状压dp 暴力存状态 然后枚举转移即可.最后注意和f[0]这个状态取max 不然一分都没有. const int MAXN= ...
- 4.11 省选模拟赛 序列 二分 线段树优化dp set优化dp 缩点
容易想到二分. 看到第一个条件容易想到缩点. 第二个条件自然是分段 然后让总和最小 容易想到dp. 缩点为先:我是采用了取了一个前缀最小值数组 二分+并查集缩点 当然也是可以直接采用 其他的奇奇怪怪的 ...
- [8.16模拟赛] 玩具 (dp/字符串)
题目描述 儿时的玩具总是使我们留恋,当小皮还是个孩子的时候,对玩具更是情有独钟.小皮是一个兴趣爱好相当广泛且不专一的人,这这让老皮非常地烦恼.也就是说,小皮在不同时刻所想玩的玩具总是会不同,而有心的老 ...
- 2014 Super Training #10 D 花生的序列 --DP
原题: FZU 2170 http://acm.fzu.edu.cn/problem.php?pid=2170 这题确实是当时没读懂题目,连样例都没想通,所以没做了,所以还是感觉这样散漫的做不好,有些 ...
- 模拟赛20181016 dp
给出1-n的序列插入一个bst: 给出T组询问,包含n,h分别代表点数为n,高度为h的树,求所有插入顺序的合法方案数,模1e9+7 样例输入 1 2 1 样例输出 2 #include<bit ...
随机推荐
- vmware centOS上网配置笔记
⦁ 修改/etc/sysconfig/network-scripts/ifcfg-eth0文件 (首先查看本机vmware 虚拟网络编辑器中的网关) 重启网络 使用命令:service net ...
- [模板]非递归线段树(zkw的变异版本)
类似于zkw,但空间只用两倍,zkw要4倍. 链接 可以下传标记,打熟后很好码. #include <set> #include <cmath> #include <cs ...
- 莱布尼兹三角形(C++)
[问题描述] 如下图所示的三角形,请编程输出图中排在第 n 行从左边数第 m 个位置上的数. [代码展示] # include<iostream># include<cstdio&g ...
- 【转载】JAVA常见面试题及解答(精华)
JAVA常见面试题及解答(精华) 1)transient和volatile是java关键字吗?(瞬联) 如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.例如: ...
- c# html 导出word
[CustomAuthorize] public FileResult ExportQuestionCenterWord(SearchBaseQuestion search) ...
- 用命令从mysql中导出/导入表结构及数据
在命令行下mysql的数据导出有个很好用命令mysqldump,它的参数有一大把,可以这样查看:mysqldump最常用的:mysqldump -uroot -pmysql databasefoo t ...
- Thunder团队第五周 - Scrum会议3
Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:王航 工作照片: 苗威同学在拍照,所以不在照片内. 参会成员: 王航(Master):http://www. ...
- NIO初探
NIO的前世今生 NIO又叫NonBlockingI/O,即非阻塞I/O.以此对应的,有一个更常见的IO(BIO),又叫Blocking I/O,即阻塞IO,两种都为Java的IO实现方案. NIO/ ...
- c# 生成的没用文件
1.pdb 2.vhost 3.application 4.含有更新功能(更新文件夹)
- Java 变量和输入输出
一些重要知识 一个源文件里只能有一个public类,其它类数量不限.文件名与public类名相同 JAVA程序严格区分大小写 JAVA应用程序的执行入口是main方法固定写法:public stati ...