bzoj4621: Tc605
应要求写一下这个题的题解。
我的DP很奥(奇)妙(怪),不过跟标算还是殊途同归的(反正怎么做都行……)
先讲一下奥妙的性质吧。
首先,在最终序列中,每个数最多出现一段,并且,对于出现的数,每段数两两之间的相对位置相较原序列保持不变。
然后,你还可以发现,一个数可以延伸到最左的左端点、和最右的右端点,这些都是可以算出来的。
如果我们不考虑操作次数的限制,这个问题就变成了,按顺序给你一堆区间,让你在每个区间里选一小段,使选出来的区间不重叠地覆盖整个序列,并且区间之间的相对位置要按照给定的顺序。
下面考虑次数限制,可以发现,对于一个合法的目标序列(合法的意思就是符合前面的要求,对应到题目就是能够通过操作得到),最优的操作方案显然是按由小到大的顺序对每个数进行操作,并且对每个数之多操作1次。
进一步考虑,发现,对于一个数,我们不需要对它进行操作,当且仅当该数不在最终序列中出现,或者该数在最终序列中出现的位置恰好仅为该数在原序列中的位置。
换句话说,操作k次就是限制了,你的最终序列只能有k段数(如果一个数只在原序列出现的位置出现,那么就不算一段数,需要特判)
之后就是dp,令dp[k][i]表示现在已经有k段数,并且当前计算到原序列左起第i个数的段。
作者太懒了,反正是普及组DP,你们自己脑补好了,那个特判还是要想一想的(对于我这种老年选手)。
(我觉得我已经说得很详细了啊TaT)
(嘛...主要是好困想碎叫QuQ)
代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <cstdlib>
- #include <algorithm>
- #define ll long long
- #define N 505
- #define P 1000000007
- using namespace std;
- inline int read(){
- int ret=0;char ch=getchar();
- while (ch<'0'||ch>'9') ch=getchar();
- while ('0'<=ch&&ch<='9'){
- ret=ret*10-48+ch;
- ch=getchar();
- }
- return ret;
- }
- int kk;
- int n,a[N];
- int l[N],r[N];
- int dp[N][N],dlt[N];
- int main(){
- n=read();kk=read();
- for (int i=1;i<=n;++i) a[i]=read();
- memset(dp,0,sizeof(dp));dp[0][0]=1;
- for (int i=1;i<=n;++i){
- int l,r;
- for (l=i;l>1&&a[l-1]<a[i];--l);
- for (r=i;r<n&&a[r+1]<a[i];++r);
- (dp[kk][i]+=dp[kk][i-1])%=P;
- for (int k=kk-1;k>=0;--k){
- dlt[l-1]=0;
- for (int j=l;j<=r;++j) dlt[j]=(dlt[j-1]+dp[k][j-1])%P;
- for (int j=l;j<=r;++j) (dp[k+1][j]+=dlt[j])%=P;
- (dp[k][i]+=dp[k][i-1])%=P;
- (dp[k+1][i]+=P-dp[k][i-1])%=P;
- }
- }
- int ans=0;
- for (int i=0;i<=kk;++i) (ans+=dp[i][n])%=P;
- printf("%d\n",ans);
- return 0;
- }
bzoj4621: Tc605的更多相关文章
- BZOJ4621 Tc605(动态规划)
容易发现最终序列所有数字的相对顺序不变,一个数字可能的覆盖范围由两边第一个比它大的数决定,且若不考虑次数限制所有这样的序列都可以变换得到.对于一个序列,其需要的最少变换次数显然就是覆盖了别的位置的数的 ...
- 【BZOJ4621】Tc605 DP
[BZOJ4621]Tc605 Description 最初你有一个长度为 N 的数字序列 A.为了方便起见,序列 A 是一个排列. 你可以操作最多 K 次.每一次操作你可以先选定一个 A 的一个子串 ...
- bzoj 4621 Tc605 思想+dp
4621: Tc605 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 328 Solved: 183[Submit][Status][Discuss ...
- bzoj 4621: Tc605 动态规划
题解: 一道比较简单的题目 想着想着就把题目记错了..想成了可以把某段区间覆盖为其中一个数 其实是比较简单的 每个点的贡献一定是一个区间(就跟zjoi2018那题一样) 然后问题就变成了给你n个区间让 ...
- BZOJ 4621: Tc605
Description 最初你有一个长度为 N 的数字序列 A.为了方便起见,序列 A 是一个排列. 你可以操作最多 K 次.每一次操作你可以先选定一个 A 的一个子串,然后将这个子串的数字全部变成原 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- SpringMVC + Spring + MyBatis 整合 + Spring shrio + easyUI + 权限管理框架,带shrio session和shrio cache集群实现方案
工作之余先来写了一个不算规范的简单架子 基于spring mvc + spring + mybatis + Spring shrio 基于redis的集群方案 系统权限部分,分成多个机构,其中每个机构 ...
- Android版本和API Level对应关系
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html Platform Version API ...
- (八)Eclipse创建Maven项目运行mvn命令
1.Eclipse创建Maven项目 使用Eclipse创建一个Maven项目非常的简单,选择菜单项File>New>Other(也可以在项目结构空白处右击鼠标键),在弹出的对话框中选择M ...
- Node.js 教程 04 - 模块系统
前言: Node.js的模块系统类似于C/C++的文件引用,可以声明对象,也可以定义类 创建对象. 大家这么理解,就简单了. 定义: 为了让Node.js的文件可以相互调用,Node.js提供了一个简 ...
- Windows API 函数列表 附帮助手册
所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...
- MS SQL巡检系列——检查外键字段是否缺少索引
前言感想:一时兴起,突然想写一个关于MS SQL的巡检系列方面的文章,因为我觉得这方面的知识分享是有价值,也是非常有意义的.一方面,很多经验不足的人,对于巡检有点茫然,不知道要从哪些方面巡检,另外一方 ...
- 分布式一致性算法--Paxos
Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法.Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致.在工程实践意义上来说, ...
- Java 消息摘要 散列 MD5 SHA
package xxx.common.util; import java.math.BigInteger; import java.security.MessageDigest; import jav ...
- Windows Server 2012 虚拟化实战:网络(二)
关于Windows Server的虚拟化网络,前文描述了在操作系统层面上的出现的配置变化.其中的一些配置通过Windows Server提供的小工具即可实现,如网卡组的配置,而有些需要安装Window ...
- 异步方法的意义何在,Async和await以及Task的爱恨情仇,还有多线程那一家子。
前两天刚感受了下泛型接口的in和out,昨天就开始感受神奇的异步方法Async/await,当然顺路也看了眼多线程那几个.其实多线程异步相关的类单个用法和理解都不算困难,但是异步方法Async/awa ...