题目传送门

  传送门

题目大意

  给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减。

  考虑将相邻的相等的数缩成一个数。

  假设没有分成了$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 - 动态规划的更多相关文章

  1. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  2. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  3. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  4. 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 ...

  5. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

  6. CodeForces Gym 100213F Counterfeit Money

    CodeForces Gym题目页面传送门 有\(1\)个\(n1\times m1\)的字符矩阵\(a\)和\(1\)个\(n2\times m2\)的字符矩阵\(b\),求\(a,b\)的最大公共 ...

  7. Codeforces GYM 100876 J - Buying roads 题解

    Codeforces GYM 100876 J - Buying roads 题解 才不是因为有了图床来测试一下呢,哼( 题意 给你\(N\)个点,\(M\)条带权边的无向图,选出\(K\)条边,使得 ...

  8. codeforces Gym 100187J J. Deck Shuffling dfs

    J. Deck Shuffling Time Limit: 2   Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...

  9. Codeforces Gym 100187K K. Perpetuum Mobile 构造

    K. Perpetuum Mobile Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...

随机推荐

  1. 聊天机器人開發好消息!!DIALOGFLOW與微信的天作之合!!

    虽然DIALOGFLOW暂未能够与微信(WECHAT)或企业微信(ENTERPRISE WECHAT)进行任何技制上的连接INTERGRATION),确实限制了我们这些聊天机器人开发者的创作空间,因为 ...

  2. TCP断开那些事

    继上一篇后,我们再来看一下四次挥手的过程 这里其实没有必要过多阐述,一张图胜过千言万语. 与三次握手一样,四次挥手的过程中也有许多扩展问题. 当然问的最多的还是:为什么要四次握手?为什么要等待2MSL ...

  3. Python全局变量和局部变量相关知识点

    知识点一: #在函数外面定义的变量叫全局变量 num = 100 def AAA(): ''' 如果在函数中直接修改全局变量,那么会产生异常 如果真的需要修改,可以在函数中进行声明(前面加入globa ...

  4. [ipsec][strongswan] 使用wireshark查看strongswan ipsec esp ikev1 ikev2的加密内容

    一,编译,启用strongswan的save-keys plugin ./configure --prefix=/root/OUTPUT --exec-prefix=/root/OUTPUT --en ...

  5. kubernetes in action - Volumes

    Volume解决Kubernetes的存储的问题 对于Pod使用的存储,抽象为volume,volume伴随着Pod的创建而创建,消失而同时消失,不能单独的创建 这样的好处,是存储的塑胶不会因为某个c ...

  6. 魔方---java

    package LMS; import java.awt.AWTException;import java.awt.Robot;import java.awt.event.InputEvent;imp ...

  7. PL_SQL学习

    打印输出: dbms_output.put_line('AA'); 显示服务器输出信息  set serveroutput on; 打印出eid=1的员工姓名: declare v_name varc ...

  8. SharePoint 2013 拷贝文件夹到本地

    网站--设计(小齿轮)--网站内容--文档库--打开文档库后---单击标题--库--找到下图的红色框的图标. 其名称[使用资源管理器打开] 打开后所有的操作都像资源管理器的操作方式一样

  9. JS中使用base64编码上传下载文件

    下载文件:使用FileSaver.js   https://github.com/eligrey/FileSaver.js/blob/master/README.md 手机端UC浏览器无法下载  安卓 ...

  10. react github项目

    https://github.com/bailicangdu/react-pxq 网址;https://github.com/bailicangdu/react-pxq