题目大意:给你一个序列,让你提取出一个子序列A,剩余的部分组成子序列B,现定义seg(x)表示把序列x中相邻的相同数合并成一个数后,序列x的长度,分别求seg(A)+seg(B)的最大值和最小值,n=1e5

考场上并没有想出最小值做法,只会最大值的贪心,下考才知道可以DP做??

最大值的贪心:

维护$nxt[i]$表示$a[i]$下一次出现的位置。再模拟构造两个序列的过程,新加进来的数放在序列尾元素的$nxt$较小的序列

 1 #include <cmath>
2 #include <queue>
3 #include <vector>
4 #include <cstdio>
5 #include <cstring>
6 #include <algorithm>
7 #define ll long long
8 #define ull unsigned long long
9 #define dd double
10 using namespace std;
11 const int N1=105; const ll inf=0x3f3f3f3f3f3f3f3fll;
12
13 int n;
14 int a[N1],b[N1],c[N1],nxt[N1],la[N1],cntb,cntc;
15
16 int main()
17 {
18 scanf("%d",&n);
19 for(int i=1;i<=n;i++) scanf("%d",&a[i]);
20 int i,j,ans=0;
21 for(i=n;i>=1;i--)
22 {
23 if(!la[a[i]]) la[a[i]]=i, nxt[i]=n+1;
24 else nxt[i]=la[a[i]], la[a[i]]=i;
25 }
26 nxt[0]=n+1;
27 for(i=1;i<=n;i++)
28 {
29 if(a[i]==a[b[cntb]]&&a[i]==a[c[cntc]]){
30 if(b[cntb]>c[cntc]) c[cntc]=i;
31 else b[cntb]=i;
32 }else if(a[i]==a[b[cntb]]){
33 c[++cntc]=i;
34 }else if(a[i]==a[c[cntc]]){
35 b[++cntb]=i;
36 }else{
37 if(a[b[cntb]]==a[c[cntc]]){
38 if(b[cntb]>c[cntc]) c[++cntc]=i; //改小的
39 else b[++cntb]=i;
40 }else{
41 if(nxt[b[cntb]]<=nxt[c[cntc]]) b[++cntb]=i;
42 else c[++cntc]=i;
43 }
44 }
45 }
46 printf("%d\n",cntb+cntc);
47 return 0;
48 }

最小值的DP:

首先一步贪心,把相邻的相同元素都合并,这样新的序列里一定没有相同的相邻元素

题目里把序列划分成$01$序列,我们$DP$每个01or10分界点!

维护$f[i][0/1]$表示第$i$个元素放在$0/1$,第$i-1$个元素放在$1/0$时的答案

也就是$j~i-1$的元素放在一个序列里,再把$i$接在$j-1$所在序列的后面

可得方程$f[i][0/1]=f[j][1/0]+i-j-(a[i]=a[j-1])$

利用前缀和优化成$O(n)$

 1 #include <cmath>
2 #include <queue>
3 #include <vector>
4 #include <cstdio>
5 #include <cstring>
6 #include <algorithm>
7 #define ll long long
8 #define ull unsigned long long
9 #define dd double
10 using namespace std;
11 const int N1=100005; const int inf=0x3f3f3f3f;
12
13 int n,nn;
14 int a[N1],b[N1],f[N1][2],mval[N1][2];
15
16 int main()
17 {
18 scanf("%d",&nn);
19 for(int i=1;i<=nn;i++) scanf("%d",&b[i]);
20 for(int i=1;i<=nn;i++) if(b[i]!=b[i-1]) a[++n]=b[i];
21 memset(mval,0x3f,sizeof(mval)); a[0]=-1;
22 // mi[1][0]=f[1][0]=1;
23 f[1][0]=1; f[1][1]=inf;
24 int mf[2]={0,inf};
25 for(int i=2;i<=n;i++)
26 {
27 f[i][0]=min(mval[a[i]][1]+i-1,mf[1]+i);
28 f[i][1]=min(mval[a[i]][0]+i-1,mf[0]+i);
29 mf[0]=min(f[i][0]-i,mf[0]); mf[1]=min(f[i][1]-i,mf[1]);
30 mval[a[i-1]][0]=min(mval[a[i-1]][0],f[i][0]-i);
31 mval[a[i-1]][1]=min(mval[a[i-1]][1],f[i][1]-i);
32 }
33 printf("%d\n",min(f[n][0],f[n][1]));
34 return 0;
35 }

CF1479B Painting the Array(贪心+DP)的更多相关文章

  1. CF1155D Beautiful Array 贪心,dp

    CF115DBeautiful Array 题目大意:给一个有n个元素的a数组,可以选择其中一个区间的所有数都乘上x,也可以不选,求最大子序列和. 如果没有前面的操作,就是只求最大子序列和,我们都知道 ...

  2. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  3. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  4. 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp

    正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...

  5. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  6. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

  7. hdu 1257 最少拦截系统【贪心 || DP——LIS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  8. 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人

    P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...

  9. 贪心+dp

    贪心+dp 好多题都是这个思想, 可以说是非常重要了 思想一: 在不确定序列无法dp的情况下, 我们不妨先假设序列已经选定, 而利用贪心使序列达到最优解, 从而先进行贪心排序, 在进行dp选出序列 思 ...

随机推荐

  1. nginx 配置文件与日志模块

    内容概要 Nginx 虚拟主机 基于多 IP 的方式 基于多端口的方式 基于多域名的方式 日志配置(日志格式详解) Nginx 访问控制模块(可以去 Nginx.org 文档 documentatio ...

  2. python内置模块之re模块

    内容概要 re模块常用方法 findall search match re模块其他方法 split sub subn compile finditer findall 对无名分组优先展示 re实战之爬 ...

  3. python的format

    python的format 就是一个参数传递+格式化的过程 参数传递 1.位置传递,默认 fmt = "{} {}" fmt.format("hello",&q ...

  4. 免费开源Blazor在线Ico转换工具

    行文目录 功能效果演示 实现说明 2.1 其他图片上传 2.2 核心代码:其他图片转Ico 2.3 转换后的Ico文件下载 总结 1. 功能效果演示 仓库地址:IcoTool 在线演示地址:https ...

  5. Prometheus之Dockerfile编写、镜像构建、容器启动

    目录 从官方镜像启动:prom/prometheus 官方Dockerfile分析 编写自己的Dockerfile 构建镜像: 启动容器: 从官方镜像启动:prom/prometheus 拉取镜像 $ ...

  6. .Net Core AOP之IExceptionFilter

    一.简介 在.net core 中Filter分为以下六大类: 1.AuthorizeAttribute(权限验证) 2.IResourceFilter(资源缓存) 3.IActionFilter(执 ...

  7. [题解]Codeforces Round #519 - C. Smallest Word

    [题目] C. Smallest Word [描述] IA有一个由若干个'a'和'b'组成的字符串,IA可以翻转该字符串的任意长的前缀,IA想通过这样的操作得到一个字典序最小的字符串,求一种可能的翻转 ...

  8. 思迈特软件Smartbi光鲜亮丽的背后是什么在支撑?

    思迈特软件Smartbi是国内知名BI厂商,自2011年成立以来就以提升和挖掘客户的价值为使命,致力于为客户提供一站式商业智能平台和BI解决方案,发展到如今已经获得了来自国家.地方政府.国内外权威分析 ...

  9. String类型转int类型方法

    System.out.println( "Integer.parseInt(\"5\") =" + Integer.parseInt("5" ...

  10. Linux下忘记MySQL密码的解决办法

    一.使用免密码登录 1.使用 #find / -name my.cfg 找到mysql配置文件 2.vim /etc/mysql/my.cfg (我的配置文件是这个路径,每个人的路径可能有所不同,用f ...