HDU5489 LIS变形

Removed Interval

Problem Description

Given a sequence of numbers A=a1,a2,…,aN

, a subsequence b1,b2,…,bk

of A

is referred as increasing if b1<b2<…<bk

. LY has just learned how to find the longest increasing subsequence (LIS).
Now that he has to select L

consecutive numbers and remove them from A

for some mysterious reasons. He can choose arbitrary starting position of the selected interval so that the length of the LIS of the remaining numbers is maximized. Can you help him with this problem?

Input

The first line of input contains a number T

indicating the number of test cases (T≤100

).
For each test case, the first line consists of two numbers N

and L

as described above (1≤N≤100000,0≤L≤N

). The second line consists of N

integers indicating the sequence. The absolute value of the numbers is no greater than 109

.
The sum of N over all test cases will not exceed 500000.

Output

For each test case, output a single line consisting of “Case #X: Y”. X

is the test case number starting from 1. Y

is the maximum length of LIS after removing the interval.

Sample Input

2
5 2
1 2 3 4 5
5 3
5 4 3 2 1

Sample Output

Case #1: 3
Case #2: 1

题意:一个含有n个元素的数组,删去k个连续数后,求LIS

题解:定义l[i]为  以第i个数结尾,删除i-k-1到i-1这k个数的LIS

定义r[i]为 以i开头到n的LIS

因为这样我们会忽略删除最后K个数的情况,所以我们n+1   最后一个元素赋值为无穷大

答案就是 l[i]+r[i]-2;

///1085422276

#include<bits/stdc++.h>
using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){
        if(ch==‘-‘)f=-1;ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘){
        x=x*10+ch-‘0‘;ch=getchar();
    }return x*f;
}
//****************************************
const int  N=100000+50;
#define mod 1000000007
#define inf 1000000007

int b[N],a[N],dp[N],l[N],r[N],n,L;

int main() {
  int T=read();int oo=1;
  while(T--) {
     mem(a),mem(b);
     scanf("%d%d",&n,&L);
     for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
     }a[++n]=inf;
     for(int i=1;i<=n;i++) {
        b[n-i+1]=-a[i];
     }
     fill(dp+1,dp+n+1,inf+2);
     for(int i=L+1;i<=n;i++) {
        int tmp=lower_bound(dp+1,dp+n+1,a[i])-dp;
        l[i]=tmp;
        tmp=lower_bound(dp+1,dp+n+1,a[i-L])-dp;
        dp[tmp]=a[i-L];
     }
     fill(dp+1,dp+n+1,inf);
     for(int i=1;i<=n;i++) {
        int tmp=lower_bound(dp+1,dp+n+1,b[i])-dp;
        r[n-i+1]=tmp;
        dp[tmp]=b[i];
     }
     //for(int i=1;i<=n;i++)cout<< l[i]<<" ";
     //cout<<endl;
     //for(int i=1;i<=n;i++)cout<< r[i]<<" ";
     int ans=0;
     for(int i=L+1;i<=n;i++) {
        ans=max(ans,l[i]+r[i]-2);
     }
     printf("Case #%d: ",oo++);
     cout<<ans<<endl;
  }
  return 0;
}

代码

时间: 2024-08-27 20:09:58

HDU5489 LIS变形的相关文章

hdu 1087(LIS变形)

Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31458    Accepted Submission(s): 14128 Problem Description Nowadays, a kind of chess game called “Super Jumping!

HDU1160_FatMouse&#39;s Speed【LIS变形】

FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9624    Accepted Submission(s): 4284 Special Judge Problem Description FatMouse believes that the fatter a mouse is, the faster

NBUT 1116 Flandre&#39;s Passageway (LIS变形)

题意:给一个有n*m格子的矩形,设每格边长100,要从(1,1)走到(n,m)需要耗(n+m)*100,但是其中有一些格子是可以直接穿过的,也就是走对角线,是100*根号2长,给出k个可以穿过的格子,要求最短路径是多少? 思路:研究一下知道当选择了某个可穿过的格子(x,y),那么对于任意格子(>x,y)和(x,>y)都是不能再选的,因为这样会更长,也就是说同一行最多只能选一个格子穿过.一开始想到的是在一个拓扑序列中求最小路径的权之和,这个模型倒是没错,但是怎么建立一个这样的图就麻烦了.再想到用

挖地雷(LIS变形)

挖地雷(LIS变形)  AC_Code: 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <string> 7 #include <vector> 8 #include <queue> 9 #include <vector>

登山(LIS变形)

登山(LIS变形) 注意读题:不连续两个相同海拔,所以要么严格递增,要么严格递减 AC_Code 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <cmath> 6 #include <cstdlib> 7 #include <queue> 8 #include <vector&

hust校赛 f题 The tree of hust(lis 变形)

题目大意是给出一段数字序列,可以忽略一次一段连续的序列,求忽略后的最长连续上升子序列 思路是dp,用end数组记录以当前元素作为结尾的最长连续上升序列的元素个数,那么不难得到状态转移方程为 dp(i) = max(dp(i - 1),  max( end[k] ) ) + 1 代码如下: #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostr

hdu5773--The All-purpose Zero(LIS变形)

题意:给一个非负整数的数列,其中0可以变成任意整数,包括负数,求最长上升子序列的长度. 题解:LIS是最简单的DP了,但是变形之后T^T真的没想到.数据范围是10^5,只能O(nlogn)的做法,所以一直在想0要插到哪里. 题解是先求不包括0的数列的LIS,再将0插入其中,由于直接插入不会保证递增,对其他数字进行处理,就是减去这个数字前面0的个数. 这个可以理解成优先选择0,所以一个数如果要被选中,就要大于中间这个0插入后变成的数,当然不用担心这样不对,因为如果一个数因为处理后不能选进,其实0也

UVa 1471 (LIS变形) Defense Lines

题意: 给出一个序列,删掉它的一个连续子序列(该子序列可以为空),使得剩下的序列有最长的连续严格递增子序列. 分析: 这个可以看作lrj的<训练指南>P62中讲到的LIS的O(nlogn)的优化变形过来的问题. 预处理: Li是第i个元素Ai向左延伸的最大长度,即[i, i + Li - 1]是一个递增区间 同样地,Ri是第i个元素向右延伸的最大长度. 我们,可以枚举i, j(j<i 且 Aj < Ai),这样就可以把Aj和Ai“拼接”起来,所得到的最长连续递增子列的长度就是Lj

POJ 1836-Alignment(DP/LIS变形)

Alignment Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13465   Accepted: 4336 Description In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers are aligned in a straight line in front of the cap