Codeforces #323 div2. D Once Again... dp LIS
来源:互联网 发布:淘宝卖家发布宝贝教程 编辑:程序博客网 时间:2024/04/25 17:14
题目
题目链接:http://codeforces.com/problemset/problem/582/B
题目来源:CF #323 div2D/ div1 B
简要题意:求序列
a 重复T 次后的最长不下降子序列(LNDS)数据范围:
1 ≤ n ≤ 100;1 ≤ T ≤ 107;
题解
当
T 比较小直接Θ(nTlognT) 求出答案就行了。当
T 很大的时候,一个很直观的想法其中肯定有一段是平的,且这个ai 应该是出现次数最大的。设出现最多的为
amax ,出现camax 次,LNDS中每段a 对应的数字中除了全amax 的以外应该每段都有至少两种数字,不然可以删掉这段换成一段amax ,长度不会减小。每增加一段LNDS的结尾至少增加
1 ,所以最多只需要n 段a 就可以构造出成段amax 外的序列。于是知道
n 段a 中amax 为结尾的LNDSlisl 和amax 为开头的LNDSlisr 就能知道答案。结果为
lisl+(T−2n)camax+lisr
实现
使用类似LIS方法去做LNDS,
lower_bound
改成upper_bound
即可对于
amax 为结尾的LNDS,顺序求出再做个upper_bound
就行了。对于
amax 为开头的LNDS,无法用之前的结果直接做出来,需要转化。
amax 为开头的LNDS就是反转序列中amax 为结尾的最长不上升子序列。继续统一,
amax 为开头的LNDS就是将序列反转,所有元素取相反数后−amax 为结尾的LNDS。于是现在只要会求结尾LNDS就能搞了。
代码
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define sz(x) ((int)(x).size())#define fi first#define se secondusing namespace std;typedef long long LL;typedef vector<int> VI;typedef pair<int,int> PII;LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}// headconst int INF = 0x3f3f3f3f;int LIS[100000];int RLIS[100000];int a[305];int cnt[305];int rev[305];int getLIS(int *LIS, int *a, int n, int t) { int len = 0; LIS[0] = INF; for (int i = 0; i < t; i++) { for (int j = 0; j < n; j++) { *upper_bound(LIS, LIS+len, a[j]) = a[j]; if (LIS[len] != INF) LIS[++len] = INF; } } return len;}int main(){ int n, t; scanf("%d%d", &n, &t); for (int i = 0; i < n; i++) { scanf("%d", a+i); cnt[a[i]]++; rev[n-1-i] = -a[i]; } if (t < 300) { printf("%d\n", getLIS(LIS, a, n, t)); return 0; } int len = getLIS(LIS, a, n, n); int lenr = getLIS(RLIS, rev, n, n); int ans = 0; for (int i = 0; i <= 300; i++) { if (!cnt[i]) continue; int temp = (t-2*n)*cnt[i]; temp += upper_bound(LIS, LIS+len, i)-LIS; temp += upper_bound(RLIS, RLIS+lenr, -i)-RLIS; ans = max(temp, ans); } printf("%d\n", ans); return 0;}
0 0
- Codeforces #323 div2. D Once Again... dp LIS
- #Codeforces 323 [div2] D. Once Again 【优化dp】
- Codeforces #323 D. Once Again... (LIS)
- CF#323-DIV2-D. Once Again-暴力贪心LIS
- codeforces 583 D. Once Again... (LIS + 贪心)
- codeforces#323(div2) D. Once Again... 最长不下降子序列
- Codeforces Round #323 D Once Again...
- Codeforces 582 B Once Again... (LIS)
- Codeforces 582B Once Again... 【LIS变形】
- Codeforces 582B Once Again... LIS变形
- codeforces 583B B. Once Again...(LIS)
- Codeforces Round #323 (Div. 2) D.Once Again...(582B)
- 【17.07%】【codeforces 583D】Once Again...
- 【Codeforces Round 323 (Div 2)D】【暴力 脑洞 插入贡献思想】Once Again... 循环节重复T次后的LIS
- codeforces 583B B. Once Again...(dp)
- CodeForces - 582B Once Again... (LIS变型)好题
- codeforces Round 323D Once again(周期数列的最长非递减子序列)
- Codeforces 582B Once Again...
- 代理模式
- CAN与CANOpen(一)
- 股票入门基础知识
- Android 数据存储--文件存储
- 20151003&&20151004题解
- Codeforces #323 div2. D Once Again... dp LIS
- 项目3——括号的匹配
- POJ1001 Exponentiation(高精度幂)
- String、StringBuffer、StringBuilder区别及使用场合
- pygame编写的坦克游戏(二)
- V210 SPI驱动分析
- Explore File data cannot open
- 第1章 linux概述
- Palindrome Number