20181225模拟赛 T1 color (转化思想,分拆思想)
题目:
有⼀块有 n 段的栅栏,要求第 i 段栅栏最终被刷成颜色 ci 。每⼀次可以选择 l, r 把第l . . . r 都刷成某种颜色,后刷的颜⾊会覆盖之前的。⼀共有 m 种颜色,雇主知道只需要用m 次就能达成目标,因此你只能刷 m 次。但是你还是可以想办法磨洋工,你希望最⼤化 m 次刷漆选择的区间长度(r − l + 1)总和。
分析:
这个题目有一种似曾相识的感觉……
罢了……人生三大错觉——手机振动、有人敲门、这题我会……
这个题呢,题目里有提到,只需要m次即可完成涂色,这说明什么?
每种颜色最多只需涂色一次,这个条件可以转化为,当序列中出现两个颜色相同时,绝对不存在一对相同的颜色与这一对交叉。
可以举个栗子,有可能出现“1 2 3 1”这样的颜色序列,但绝不可能出现“1 2 1 2”这样的子序列(如果出现了,m对无法将全部颜色染齐),所以如果序列中有颜色相同,那么相同的颜色绝对是一层一层的(感性理解),像这样“1 2 3 3 2 4 2 1”。
我们不能无脑乱涂,如果层数多了,先涂哪种颜色对我们最终的答案都是有影响的,我们的程序根本处理不了这样的智能问题。
那么一个思路就出来了。我们是否可以把每种颜色(一定有一个出现的最左端点和一个最右端点)和它横跨的长度抠出来,一部分一部分的计算?
比如这样一个序列(稍微简单一些):1 2 4 3 2 6 5 2 7 8 9
可以看到,重复出现的颜色只有2,我们就用这个例子理解一下这种思想
假如一个序列中颜色尽不相同,像“1 2 3 4……”这种,是不是很好解决,直接从一段开始,每次将一个颜色一直染到另一端。
我们将上面那个序列拆分后也成为这种感觉,只不过在“1 2 3 4……”这个序列,每一个颜色的长度都是1,对答案的贡献都是1,我们将上面那个序列拆分后,拆成这样:
① 1 (2 * * * * * *) 7 8 9
② 4 3
③ 2 6
“*”号代表我们拆出来的序列①中,2这个颜色占有的长度范围,这样,我们就简化了原来的序列,但是,序列①和序列②③不同的地方又在于,我们不能无脑地从一段开始“扫射”,因为对于不同的涂法,最后“磨洋工”的时间也是不同的,但我们发现,这种元素相互之间贡献简单的序列,可以被我们拿来做区间dp,所以又套了一个区间dp的思想,也成功神化了这道题。
这样呢,把我们拆出来的每一个序列单独跑区间dp,每次贡献答案,即是结果了。
实现难度主要在维护一个p数组,其他的没什么难度,我会在代码里给注释的。
(这份代码是我抄的std,感谢此题的代码贡献者,写出了能让我读懂的代码)
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=,M=;
int a[N],n,m,cnt,l[M],r[M],p[N];
ll s[M],f[M][M];
ll calc(){
for(int i=;i<=cnt;i++) s[i]+=s[i-];
for(int i=cnt;i;i--)
for(int j=i;j<=cnt;j++)
f[i][j]=max(f[i][j-],f[i+][j])+s[j]-s[i-];
return f[][cnt];
} int main(){
// freopen("color.in","r",stdin);
// freopen("color.out","w",stdout);
scanf("%d%d",&n,&m);ll ans=;
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n;i++) r[a[i]]=i;
for(int i=n;i;i--) l[a[i]]=i;
for(int i=;i<=m;i++) p[l[i]]=i;
for(int i=;i<=n;i++)
if(p[i]){//p数组存的是这个位置是
cnt=;int x=i;//哪个字母出现的最左端
while(p[x]){
int y=p[x];
p[x]=;s[++cnt]=r[y]-l[y]+;
x=r[y]+;
} ans+=calc();
} cout<<ans<<endl;
return ;
}
color
20181225模拟赛 T1 color (转化思想,分拆思想)的更多相关文章
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 20180610模拟赛T1——脱离地牢
Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要 ...
- NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)
题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...
- 2017-9-3模拟赛T1 卡片(card)
题目 [题目描述] lrb 喜欢玩卡牌.他手上现在有n张牌,每张牌的颜色为红绿蓝中的一种.现在他有两种操作.一是可以将两张任意位置的不同色的牌换成一张第三种颜色的牌:二是可以将任意位置的两张相同颜色的 ...
- [NOIP2018校模拟赛]T1聚会 party
题目链接: 聚会 分析: 设每个点到1号点的距离为dist_{i},每个点的权值为x_{i},目标点到1号点的距离为dist,权值为x,那么对于每一次查询,我们讨论三种情况: ① 目标家庭在区间左边( ...
- 「题解」:07.18NOIP模拟赛T1:星际旅行
问题 A: 星际旅行 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 考试心路历程 拿到这道题感觉很懵逼,所以先搞的T2和T3,最后码了个暴力,结果还不如直接输出‘0’得分高 ...
- light题目讲解 7.25模拟赛T1
心得:这一道题其实就是自己打暴力打出来的 没有想到正解真的就是暴力枚举 我的做法是这样的 就是枚举A字符串中长度为x的子串 看它是不是B串的子序列 接下来是我的绝望考试代码(100分AC) //lig ...
- 纪中20日c组模拟赛T1 2121. 简单游戏
T1 2121. 简单游戏 (File IO): input:easy.in output:easy.out 时间限制: 1000 ms 空间限制: 262144 KB 具体限制 Goto Pro ...
- 5.15 省选模拟赛 T1 点分治 FFT
LINK:5.15 T1 对于60分的暴力 都很水 就不一一赘述了. 由于是询问所有点的这种信息 确实不太会. 想了一下 如果只是询问子树内的话 dsu on tree还是可以做的. 可以自己思考一下 ...
随机推荐
- package-lock.json到底是干嘛的?(转载)
package-lock.json到底是干嘛的? https://mp.weixin.qq.com/s/NaVVljKrQAFmHMdbkaYmPg## nvm-windows https://git ...
- bzoj 1355: [Baltic2009]Radio Transmission【kmp】
kmp复健,答案是n-next[n] #include<iostream> #include<cstdio> using namespace std; const int N= ...
- 洛谷 P4014 分配问题 【最小费用最大流+最大费用最大流】
其实KM更快--但是这道题不卡,所以用了简单粗暴的费用流,建图非常简单,s向所有人连流量为1费用为0的边来限制流量,所有工作向t连流量为1费用为0的边,然后对应的人和工作连(i,j,1,cij),跑一 ...
- bzoj 2006: [NOI2010]超级钢琴【st表+堆】
设计一个五元组(i,l,r,p,v),表示在以i为左端点,右端点落在(l,r)中的情况下,取最大值v时右端点落在p.把这个五元组塞到优先队列里,以v排序,每次取出一个,然后把这个取过的五元组分成两个( ...
- 初学者的疑惑,到底什么是javaBean?
JavaBeans是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中.特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性.名称中的"Bea ...
- Light oj 1002 Country Roads (Dijkstra)
题目连接: http://www.lightoj.com/volume_showproblem.php?problem=1002 题目描述: 有n个城市,从0到n-1开始编号,n个城市之间有m条边,中 ...
- Drawable(6)关于StateList的补充
模板: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android=&quo ...
- Android 内存溢出处理方案
转自 : http://www.cnblogs.com/hello-ruby/archive/2013/04/19/3031098.html 首先我们来看看android内存溢出的原因,有可能是: 由 ...
- 导出数据库报错 EXP-00002: 写入导出文件时出错 EXP-00000: 导出终止失败
解决方法: 1.检查磁盘所在空间是否够用. 2.磁盘修复下 排除故障考虑的地方要全面啊.
- Spring数据访问2 - 通过JDBC访问数据库
因为原生的jdbc操作太复杂,几乎都是建立连接.关闭连接和处理例外等模板式的代码,Spring对此进行了抽象——使用模板来消除样板式代码 ,JdbcTemplate承担了简化数据库访问这块的任务. 利 ...