hdu 5489 LIS变形(删掉连续区间)
来源:互联网 发布:仿京东商城html源码 编辑:程序博客网 时间:2024/06/03 06:08
题目大意:给定一个序列长度为n,从中去掉长度为l的连续的序列,求剩余序列中的LIS,去掉的序列起始位置随意
思路:LIS变形,只要枚举去掉的所有区间就可以了,最大长度等于以区间右边第一个元素开始的LIS+区间左边的小于右边第一个元素的LIS-1.右边的直接逆序求LIS即可。
左边的常规LIS。左边的需要计算arr[i+l]在a[1……i]中的最大LIS就是我说的那个加法的后半部分。
ps:逆序求LIS有两种方法,第一种是将arr数组的所有元素取反,然后求。另外一种就是直接开始求,用upper_bound。本来前一天就该过得,但是初始化时的INF开小了,为99999999 ,tmp数组初始化也小了为0,正确的应该是999999999 , -999999999.
代码1:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#define maxn 500005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define xxx 1000000005#define INF 999999999int arr[maxn];int b[maxn];int dp[maxn] ;int g[maxn];int main(){ int t; int ncase = 1; scanf("%d" , &t); while(t--) { int n , l , k; scanf("%d %d" , &n , &l); for(int i = 1 ; i <= n ; i ++) { scanf("%d" , &arr[i]); b[i] = -arr[i]; } mem(dp , 0); for(int i = 0 ; i <= n ; i ++) g[i] = INF; // mem(g , 0x7f); for(int i = n ; i > l ; i --) //逆序LIS { k = lower_bound(g+1 , g+n+1 , b[i]) - g; dp[i] = k; g[k] = b[i]; } // mem(g , 0x7f); for(int i = 0 ; i <= n ; i ++) g[i] = INF; int ans = 0 , maxlen = 0 ; for(int i = 1 ; i <= n - l ; i ++) { k = lower_bound(g+1 , g+n+1 , arr[i+l]) - g; ans = max(ans , k + dp[i+l] - 1); //重算了i+l位置的元素,所以需要减1 k = lower_bound(g+1 , g+n+1 , arr[i]) - g; g[k] = arr[i]; maxlen = max(maxlen , k); } ans = max(ans , maxlen); //区间是最后的一段,上面个的代码不能比较,需要单独比较 printf("Case #%d: %d\n" , ncase++ , ans); } return 0;}
代码2:
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#define maxn 500005#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long long#define xxx 1000000005#define INF 999999999int dp[maxn];int dp2[maxn];int g[maxn];int tmp[maxn];int arr[maxn];int per[maxn];int main(){ int t; int ncase = 1; scanf("%d" , &t); while(t--) { int n , l; scanf("%d %d" , &n , &l); for(int i = 1 ; i <= n ; i ++) { scanf("%d" , &arr[i]); } for(int i = 0 ; i <= n ; i ++) g[i] = INF ,tmp[i] = -INF; mem(dp,0); mem(dp2,0); mem(per , 0); int ans = 0; int len = 0; for(int i = 1 ; i <= n - l; i ++) { if(i + l <= n) ///求区间右边第一个数在左边的位置 { int k2 = lower_bound(g + 1, g + n + 1 , arr[i+l]) - g; per[i+l] = k2; } int k = lower_bound(g +1, g + n +1, arr[i]) - g; dp[i] = k; g[k] = arr[i]; len = max(len , k); } ans = max(per[n] , len); for(int i = n; i > l ; i --) //求逆序LIS { int k = upper_bound(tmp + 1, tmp + n + 1, arr[i]) - tmp; dp2[i] = n+1 - (k - 1) ; tmp[k -1] = arr[i]; } for(int i = l + 1 ; i <= n ; i ++) { int res = per[i] + dp2[i] - 1; ans = max(res , ans); } ans = max(ans , dp[n-l]); printf("Case #%d: %d\n" , ncase++ , ans); } return 0;}
0 0
- hdu 5489 LIS变形(删掉连续区间)
- HDU 5489 Removed Interval (LIS,变形)
- hdu 5489 Removed Interval LIS变形
- hdu 5489 Removed Interval lis变形
- hdu 5087(LIS变形)
- hdu 5734 LIS变形
- hdu 5256 LIS变形
- HDU 5141 LIS Again LIS变形+BIT
- HDU 5773 DP LIS变形
- HDU 4521小明序列(变形的LIS)
- hdu(1069)——Monkey and Banana(LIS变形)
- HDU 5256 序列变换 (LIS变形&&STL)
- HDU 5773 The All-purpose Zero ( LIS 变形 )
- 【HDU】-5773-The All-purpose Zero(LIS变形,思维)
- HDU 5256 序列变换 (DP/LIS变形)
- HDU 5773 The All-purpose Zero (LIS变形)
- 【hdu 1087】 Super Jumping! Jumping! Jumping! (LIS变形)
- HDU 1069 Monkey and Banana LIS变形
- qqqw
- PreferenceActivity首选项使用方法
- extjs读取excel
- 聚类评价指标
- Atitit.java swing打印功能 api attilax总结
- hdu 5489 LIS变形(删掉连续区间)
- 快速下载android sdk
- 正则表达式与通配符的区别
- native app示例ContactsTest
- 在多线程中创建单例模式的双重锁定(Double-Check Locking )
- gt()和:not(:last)来控制<li>元素显示的内容
- Mysqldump备份数据库—结构+数据+存储过程、函数、触发器
- MySql存储过程—变量
- java 集合