Codeforces Gym 101623A - 动态规划
考虑将相邻的相等的数缩成一个数。
假设没有分成了$n$段,考虑最少能够减少多少划分。
我们将这个序列排序,对于权值相同的一段数可以任意交换它们,每两个相邻数在原序列的位置中如果是$i, i + 1$,那么划分的段数就可以减少1.
每次转移我们考虑添加值相同的一段。
每次转移能不能将减少的段数加一取决于当前考虑的数在前一段内有没有出现以及有没有作为最左端点。
因此我们记录一个决策与最优解不同的次优解就能转移了。
Code
/**
* Codeforces
* Gym#101623A
* Accepted
* Time: 171ms
* Memory: 18300k
*/
#include <algorithm>
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <cstdio>
using namespace std;
typedef bool boolean; #define pii pair<int, int>
#define fi first
#define sc second ostream& operator << (ostream& out, pii x) {
out << "(" << x.fi << ", " << x.sc << ")";
return out;
} template <typename T>
void pfill(T* pst, const T* ped, T val) {
for ( ; pst != ped; *(pst++) = val);
} template <typename T>
void pcopy(T* pst, const T* ped, T *pval) {
for ( ; pst != ped; *(pst++) = *(pval++));
} int n;
int *ar;
pii *ps; inline void init() {
scanf("%d", &n);
ar = new int[(n + )];
for (int i = ; i <= n; i++)
scanf("%d", ar + i);
} int *ss, *st;
boolean *exi;
inline void solve() {
ps = new pii[(n + )];
ss = new int[(n + )];
st = new int[(n + )];
exi = new boolean[(n + )];
pfill(exi, exi + n + , false);
int m = , diff = ;
for (int i = ; i <= n; i++)
if (i == || ar[i] != ar[i - ])
ps[++m] = pii(ar[i], ++diff);
sort(ps + , ps + (n = m) + );
// for (int i = 1; i <= m; i++)
// cerr << ps[i] << endl;
ss[] = ;
for (int i = ; i <= n; i++)
ss[i] = ((ps[i - ].first == ps[i].first) ? (ss[i - ]) : (i));
st[n] = n;
for (int i = n - ; i; i--)
st[i] = ((ps[i + ].first == ps[i].first) ? (st[i + ]) : (i)); ss[] = st[] = ;
pii f(, -), g(-, -), cf(-, -), cg(-, -);
for (int i = ; i <= n; i++) {
if (ss[i] != i)
continue;
for (int j = max(ss[i - ], ); j <= st[i - ]; j++)
exi[ps[j].second] = true;
for (int j = ss[i], x, uval; j <= st[i]; j++) {
x = ps[j].second;
if (exi[x - ]) {
if (x - == f.second && st[i - ] > ss[i - ])
assert(x - != g.second), uval = g.first + ;
else
uval = f.first + ;
uval = max(uval, f.first);
} else
uval = f.first;
if (uval > cf.first)
cg = cf, cf = pii(uval, x);
else if (x != cg.second && uval > cg.first)
cg = pii(uval, x);
}
for (int j = max(ss[i - ], ); j <= st[i - ]; j++)
exi[ps[j].second] = false;
swap(cf, f);
swap(cg, g);
cf = pii(-, -), cg = pii(-, -);
// cerr << f << " " << g << endl;
}
printf("%d\n", n - f.first - );
} int main() {
init();
solve();
return ;
}
Codeforces Gym 101623A - 动态规划的更多相关文章
- Codeforces Gym 101252D&&floyd判圈算法学习笔记
一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...
- Codeforces Gym 101190M Mole Tunnels - 费用流
题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...
- 【Codeforces Gym 100725K】Key Insertion
Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...
- Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】
2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...
- codeforces gym 100553I
codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...
- CodeForces Gym 100213F Counterfeit Money
CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...
- Codeforces GYM 100876 J - Buying roads 题解
Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...
- codeforces Gym 100187J J. Deck Shuffling dfs
J. Deck Shuffling Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...
- Codeforces Gym 100187K K. Perpetuum Mobile 构造
K. Perpetuum Mobile Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...
随机推荐
- redis加固
一.背景描述 1.漏洞描述 Redis 因配置不当存在未授权访问漏洞,可以被攻击者恶意利用. 在特定条件下,如果 Redis 以 root 身份运行,黑客可以给 root 账号写入 SSH 公钥文件, ...
- 小白用阿里云搭载wordpress个人博客
阿里云服务已经购买多时,却一直没时间部署内容,借着这次机会自己照着博客园园友的方式用wordpress搭建了个人博客! 创建wordpress的内容就不多说了,直接附链接来源:https://www. ...
- spring注解:反射与配置
上图运行结果按下图配置文件中的配置,进行的spring扫描加载.无论是componentScan方式,还是xml配置方式,如果one是实现了一个接口的类,如one_Interface,那么在程序中用o ...
- Python3学习之路~7.3 反射
python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,该四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...
- 【转】mysql保存图片技术决定:保存二进制文件还是只保存图片相对路径,图片放在硬盘上面?
最近遇到上面这个问题,一开始我就果断否决了数据库保存图片的策略,主要是太蠢!事实上我的决定是正确的,我仅仅理解为mysql读写性能提高的境界,具体为什么可以提高?很模糊,知道我看到了这里: 大佬做的实 ...
- Java基础之数组详解
数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如 numbers[1 ...
- spring boot中使用@Async实现异步调用任务
本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...
- vue进阶--外卖商家页
一.准备工作 1.vue特性:轻量级.简洁.高效.组件化.数据驱动 2.技术分析:使用vue- resource与后端交互(ajax通信,ie9+) 使用vue-router作为前端路由 bet ...
- Django框架详细介绍---AJAX
一.概述 1.什么是JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 * ...
- hdu1693 插头dp
题意:给了一个矩阵图,要求使用回路把图中的树全部吃掉的方案树,没有树的点不能走,吃完了这个点也就没有了,走到哪吃到哪 用插头dp搞 #include <iostream> #include ...