CF1097E Egor and an RPG game
最少反链划分数 = 最长链。实现:每次找出所有极大元作为一个反链。
任意长度小于k * (k + 1) / 2的排列都能被划分为不多于k个单调序列。且这是一个紧的上界。
然后这题就可以切了。
题意:给定长为n的排列,设任长为n的排列都能被划分为不多于k个单调序列,把给定排列划分为不多于k个单调序列。
解:先求出k,然后求LIS,如果LIS >= k那么扔掉LIS递归。否则划分成反链即可。用链表实现。
- #include <bits/stdc++.h>
- const int N = , INF = 0x3f3f3f3f;
- int p[N], cnt;
- std::vector<int> v[N];
- struct Node {
- int nex, pre;
- }node[N]; int tp, head = N - , tail = N - ;
- int stk[N], top, f[N], rest, stk2[N], fr[N];
- bool vis[N];
- inline void del(int x) {
- int nex = node[x].nex, pre = node[x].pre;
- node[nex].pre = pre;
- node[pre].nex = nex;
- return;
- }
- inline int getLIS() {
- top = ;
- for(int i = node[head].nex; i != tail; i = node[i].nex) {
- int l = , r = top;
- while(l < r) {
- int mid = (l + r + ) >> ;
- if(stk[mid] < p[i]) {
- l = mid;
- }
- else {
- r = mid - ;
- }
- }
- f[i] = r + ;
- fr[i] = stk2[r];
- stk[r + ] = p[i];
- stk2[r + ] = i;
- if(r == top) ++top;
- }
- return top;
- }
- inline void erase() {
- int x = stk2[top];
- ++cnt;
- while(x) {
- del(x);
- v[cnt].push_back(p[x]);
- x = fr[x];
- }
- std::reverse(v[cnt].begin(), v[cnt].end());
- return;
- }
- inline void split() {
- while(rest) {
- ++cnt;
- int last = -;
- for(int i = node[tail].pre; i != head; i = node[i].pre) {
- if(p[i] > last) {
- v[cnt].push_back(i);
- last = p[i];
- //printf("inside %d \n", i);
- rest--;
- }
- }
- std::reverse(v[cnt].begin(), v[cnt].end());
- int len = v[cnt].size();
- for(int i = ; i < len; i++) {
- del(v[cnt][i]);
- //printf("now : %d \n", v[cnt][i]);
- v[cnt][i] = p[v[cnt][i]];
- //printf("now : %d \n", v[cnt][i]);
- }
- }
- return;
- }
- inline void solve() {
- int n;
- scanf("%d", &n);
- for(int i = ; i <= n; i++) {
- scanf("%d", &p[i]);
- node[i].nex = ;
- if(i > ) {
- node[i].pre = i - ;
- node[i - ].nex = i;
- }
- else {
- node[i].pre = head;
- node[head].nex = i;
- }
- }
- node[n].nex = tail;
- node[tail].pre = n;
- cnt = ;
- rest = n;
- int K = ;
- while(K * (K + ) / <= n) {
- ++K;
- }
- //printf("K = %d \n", K);
- /// use K-1
- while(rest) {
- int len = getLIS();
- //printf("len = %d \n", len);
- if(len >= K) {
- erase();
- K--;
- rest -= len;
- }
- else {
- split();
- rest = ;
- }
- }
- printf("%d \n", cnt);
- for(int i = ; i <= cnt; i++) {
- int len = v[i].size();
- printf("%d ", len);
- for(int j = ; j < len; j++) {
- printf("%d ", v[i][j]);
- }
- puts("");
- v[i].clear();
- }
- tp = ;
- return;
- }
- int main() {
- int T;
- scanf("%d", &T);
- while(T--) {
- solve();
- }
- return ;
- }
AC代码
CF1097E Egor and an RPG game的更多相关文章
- 【CF1097E】Egor and an RPG game(动态规划,贪心)
[CF1097E]Egor and an RPG game(动态规划,贪心) 题面 洛谷 CodeForces 给定一个长度为\(n\)的排列\(a\),定义\(f(n)\)为将一个任意一个长度为\( ...
- Codeforces 1097E. Egor and an RPG game 构造
原文链接https://www.cnblogs.com/zhouzhendong/p/CF1097E.html 题解 首先我们求出 $k = f(n) = \max\{x|\frac{x(x+1)}2 ...
- Codeforces 1097E. Egor and an RPG game
传送门 首先考虑怎么算 $f(n)$ (就是题目里面那个 $f(n)$) 发现可以构造一组序列大概长这样: ${1,3,2,6,5,4,10,9,8,7,15,14,13,12,11,...,n(n+ ...
- Hello 2019 (D~G)
目录 Codeforces 1097 D.Makoto and a Blackboard(DP 期望) E.Egor and an RPG game(思路 LIS Dilworth定理) F.Alex ...
- codeforces 1097 Hello 2019
又回来了.. A - Gennady and a Card Game 好像没什么可说的了. #include<bits/stdc++.h> using namespace std; cha ...
- 2013 Asia Changsha Regional Contest---Josephina and RPG(DP)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and ...
- 【经典】C++&RPG对战游戏
博文背景: 还记大二上学期的时候看的这个C++&RPG游戏(博主大一下学期自学的php,涵盖oop内容),一个外校的同学他们大一学的C++,大二初期C++实训要求做一个程序填空,就是这个 RP ...
- 2013长沙赛区现场赛 J - Josephina and RPG
J - Josephina and RPG Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I6 ...
- RPG的错排
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
随机推荐
- idea中选中了一个变量名,会高亮显示位于别的地方的这个变量名,那么怎么修改其他地方的高亮颜色
- 剑指offer——21正则表达式匹配
题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...
- 如何优雅的使用Objects.requireNonNull(T obj, String message)定制你的NPE异常
IDEA中习惯跟踪源码实现逻辑,多次碰到Objects.requireNonNull(T obj)这个方法,改方法主要用于提早判断对象是否为空,以便更早的抛出NPE 平时小组开发中强调程序健壮性,不允 ...
- DRF的请求响应组件
目录 DRF的请求响应组件 请求模块(request) 概念 request源码简单分析 响应模块(response) 概念 使用方法 response源码简单分析: 解析模块(parse) 概念 使 ...
- python中的线程锁
锁对象 原始锁是一个在锁定时不属于特定线程的同步基元组件.在Python中,它是能用的最低级的同步基元组件,由 _thread 扩展模块直接实现. 原始锁处于 "锁定" 或者 &q ...
- Codeforces 479【F】div3
题目链接:http://codeforces.com/problemset/problem/977/F 题意:给你一串数字序列,让你求最长上升子序列,但是这个子序列呢,它的数字得逐渐连续挨着. 题解: ...
- 查看Linux服务器公网IP
参考:https://www.cnblogs.com/pyyu/p/8545896.html 方法1:curl ifconfig.me 方法2:curl cip.cc
- pointer && reference
关注点在于区别两者之间的不同. 我们可以从两者使用的场景进行区分: 1, 是否需要存在null的情况: YES-pointer NO-reference 如果确定不会存在null的情况,那么使用ref ...
- HLS 视频加密小记
我是在ubuntu中,安装好了 ffmpeg 加密用的 key(生成一个encrypt2.key文件) openssl rand 16 > encrypt2.key 另一个是 iv(生成一段字符 ...
- Fence Obstacle Course
Fence Obstacle Course 有n个区间自下而上有顺序的排列,标号\(1\sim n\),第i个区间记做\([l_i,r_i]\),现在从第n个区间的起点s出发(显然s在\([l_n,r ...