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 ...
随机推荐
- Eclipse "Unable to install breakpoint due to missing line number attributes..."
Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...
- 《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- 关于docker
摘要: 最近很多阿里内部的同学和客户私信来咨询如何学习 Docker 技术.为此,我们列了一个路线图供大家学习Docker和阿里云容器服务.这个列表包含了一些社区的优秀资料和我们的原创文章.我们会随着 ...
- 微信小程序注册
小程序是一种新的开放能力,可以在微信内被便捷地获取和传播,同时具有出色的使用体验.开发者可以根据平台提供的能力,快速地开发一个小程序. 开放内容包括: 1.开放注册范围:企业.政府.媒体.其他组织: ...
- DevOps
DevOps DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障(QA)部门之间的沟通.协作与整 ...
- Fresco从配置到使用(最高效的图片加载框架)
Frescoj说明: facebook开源的针对android应用的图片加载框架,高效和功能齐全. 支持加载网络,本地存储和资源图片: 提供三级缓存(二级memory和一级internal ...
- AEAI HR_v1.5.2升级说明,开源人力资源管理系统
1.升级说明 本次AEAI HR升级内容主要是针对数通畅联推出AEAI ECP企业云联平台而升级的,其中对AEAI HR的各模块进行扩展,同时增加了移动门户版功能及为AEAI ECP提供数据服务接口. ...
- Excel公式 提取文件路径后缀
我们在代码中获取一个文件路径的后缀,是一个很简单的事. 如C#中,可以通过new FileInfo(filePath).Extension,或者Path.GetExtension(filePath)获 ...
- Microsoft SQL Server 2008 R2 安装卸载
问题 问题1 标题: Microsoft SQL Server 2008 R2 安装程序 ------------------------------ 出现以下错误: Could not open k ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...