补题链接:Here

计数DP讲解:Here

这是一个计数类的dp

dp[i][j]表示前i个数字中,删除j个元素的方案数

很容易得到转移方程:\(f[i][j] = f[i - 1][j - 1] + dp[i - 1][j]\)

意思就是前i个删除j个,要么从前i-1个中删除了j-1个,等于第i个也要删,要么从前i-1个删除了j个,等于第i个不删

这样还没做完,下面考虑去除重复的个数。(其实这就是个容斥的思想,先尽管算,再把重复的去除就是了)

考虑一下怎么会出现重复的情况。

……1,4,7,8,5,1

很容易发现,对于1,4,7,8,5,1这一段,删除1,4,7,8,5 和删除4,7,8,5,1 会造成重复计算。

重复的方案数是多少?其实就是第一个1前面的序列随便选加上后面的1 4 7 8 5 1后再删除1 4 7 8 5 或者4 7 8 5 1

假如是要删除j个元素,那么重复的方案数就是 \(dp[last[i] - 1][j - (i - last[i])]\)

其中 \(last[i]\) 表示前面与当前 \(a[i]\) 相同数字的最近位置

就是说,要想有重复的序列,一定是能删除完两个相同数字之间的数,也就是i-last[i]个,那么其实就是last[i]-1前面选一部分再加上这个重复的数字

那么因为要删除j个,还需要删除j-(i-last[i])个 肯定就是从last[i]-1前面选择

// RioTian 21/05/11
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
int n, m, k;
ll dp[1 << 17][11];
ll a[1 << 17], c[1 << 17], last[1 << 17];
void solve() {
memset(last, 0, sizeof last);
memset(c, 0, sizeof c);
for (int i = 1; i <= n; i++) {
cin >> a[i];
last[i] = c[a[i]]; //记录前面与当前数字相同的最近位置
c[a[i]] = i; //更新a[i]的新位置
}
for (int i = 0; i <= n; i++) dp[i][i] = dp[i][0] = 1; //初始化前i个删除i个,前i个删除0个的方案数
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= min(i - 1, m); j++) {
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod; //转移
if (last[i] != 0 && i - last[i] <= j) { //如果前面有与a[i]相同的数字 并且之间的数字不够删除
dp[i][j] = (dp[i][j] - dp[last[i] - 1][j - (i - last[i])] + mod) % mod; //去重
}
}
}
cout << dp[n][m] << endl;
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
while (cin >> n >> m >> k) solve();
return 0;
}

【每日一题】23.Removal (计数DP)的更多相关文章

  1. 牛客挑战赛17E 跳格子 计数dp

    !!!学长做过的题 正解:计数dp 解题报告: 传送门 首先思考,这题和普通的走台阶有什么区别嘛(跳格子其实和走台阶都一样的嘛quq因为走台阶比较经典所以就说的走台阶) 那显然最大的区别就是它有限制 ...

  2. 【JavaScript】【dp】Leetcode每日一题-解码方法

    [JavaScript]Leetcode每日一题-解码方法 [题目描述] 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -& ...

  3. [Hdu-5155] Harry And Magic Box[思维题+容斥,计数Dp]

    Online Judge:Hdu5155 Label:思维题+容斥,计数Dp 题面: 题目描述 给定一个大小为\(N*M\)的神奇盒子,里面每行每列都至少有一个钻石,问可行的排列方案数.由于答案较大, ...

  4. HDU5800 To My Girlfriend 背包计数dp

    分析:首先定义状态dp[i][j][s1][s2]代表前i个物品中,选若干个物品,总价值为j 其中s1个物品时必选,s2物品必不选的方案数 那么转移的时候可以考虑,第i个物品是可选可可不选的 dp[i ...

  5. [DP之计数DP]

    其实说实在 我在写这篇博客的时候 才刚刚草了一道这样类型的题 之前几乎没有接触过 接触过也是平时比赛的 没有系统的做过 可以说0基础 我所理解的计数dp就是想办法去达到它要的目的 而且一定要非常劲非常 ...

  6. HDU4815/计数DP

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4815] 简单说一下题意: 有n道题,每到题答对得分为a[ i ],假如A不输给B的最小概率是P,那么A ...

  7. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  8. 老男孩IT教育-每日一题汇总

    老男孩IT教育-每日一题汇总 第几天 第几周 日期 快速访问链接 第123天 第二十五周 2017年8月25日 出现Swap file….already exists以下错误如何解决? 第122天 2 ...

  9. 题解报告:hdu 1028 Ignatius and the Princess III(母函数or计数DP)

    Problem Description "Well, it seems the first problem is too easy. I will let you know how fool ...

  10. PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数

    PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数 最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可 ...

随机推荐

  1. Python 哈希表的实现——字典

    哈喽大家好,我是咸鱼 接触过 Python 的小伙伴应该对[字典]这一数据类型都了解吧 虽然 Python 没有显式名称为"哈希表"的内置数据结构,但是字典是哈希表实现的数据结构 ...

  2. 🔥🔥Java开发者的Python快速实战指南:探索向量数据库之文本搜索

    前言 如果说Python是跟随我的步伐学习的话,我觉得我在日常开发方面已经没有太大的问题了.然而,由于我没有Python开发经验,我思考着应该写些什么内容.我回想起学习Java时的学习路线,直接操作数 ...

  3. GUI界面实现小学生口算题卡功能(一)| 简要了解GUI

    上课没认真听,下课不好好写. 关于GUI,首先了解了一下什么是GUI: GUI(Graphical User Interface),图形用户界面.采用图形方式显示的计算机操作用户接口.与早期计算机使用 ...

  4. 【uniapp】学习笔记day02 | uniapp搭建

    起因:需要做一个小程序,家人们谁懂啊,老师我真的不会做,由于懒得看视频学习,于是只能看博客学习了. uniapp 好处: 1.不用关心适配问题 2.可以发布到各大平台的小程序 3.上手容易,使用vue ...

  5. java-EasyExcel模板导出

    前言:  需求:根据自定义模板导出Excel,包含图片.表格,采用EasyExcel 提示:EasyExcel请使用 3.0 以上版本, 对图片操作最重要的类就是 WriteCellData<V ...

  6. serdes级联时钟

    级联时钟在其他的IP领域下很少见到,在serdes中时个基本的功能. 因为高密场景下需要时钟数几十个IP,一般摆放在芯片边缘位置. 而SOC的管脚资源非常有限.因此就需要多个IP之间的ref clk进 ...

  7. [ABC282F] Union of Two Sets

    Problem Statement This is an interactive task, where your and the judge's programs interact via Stan ...

  8. Vue2.0 学习 第三组 条件语句

    本笔记主要参考菜鸟教程和官方文档编写.1.v-if在div或者之类的dom中使用v-if可以控制是否插入该dom,控制由v-if的true和false决定.如:<div id="app ...

  9. liunx系统sed命令使用

    增 sed '$行数i 新增内容' 文件名在文件里某行上面新增内容 sed '$行数a 新增内容' 文件名在文件里某行下面新增内容 -i.bak对源文件进行修改并备份修改之前源文件 #在文件里第5行上 ...

  10. 学习tinyriscv(1):安装tinyriscv的工具链

    因为毕设是CPU的低功耗设计,所以开始看cpu,打算还是先从这个tinyriscv学起,昨天把环境下好了,第一步是用git去clone代码,这个首先要下载git,然后在目标文件夹鼠标右键,选择&quo ...