您的位置:首页 > 其它

HDU 5773 The All-purpose Zero (DP最长上升子序列)

2016-07-28 17:21 393 查看
Problem Description

?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000).?? has a magic so that he can change 0 to any interger(He does not need to change all 0 to the same interger).?? wants you to help him to find out the length of the longest increasing
(strictly) subsequence he can get.

 

Input

The first line contains an interger T,denoting the number of the test cases.(T <= 10)

For each case,the first line contains an interger n,which is the length of the array s.

The next line contains n intergers separated by a single space, denote each number in S.

 

Output

For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the length of the longest increasing subsequence he can get.

 

Sample Input

2
7
2 0 2 1 2 0 5
6
1 2 3 3 0 0

 

Sample Output

Case #1: 5
Case #2: 5

HintIn the first case,you can change the second 0 to 3.So the longest increasing subsequence is 0 1 2 3 5.

 

Author

FZU

 

Source

2016 Multi-University Training Contest 4

 

最长上升子序列nlogn算法的稍微变形

关于最长上升子序列,表示也只写过几次(最长上升子序列),然后这次直接模板变形即可

扫到0的时候,更新各个长度的最末元素,将其变小,怎么变小,前面一个长度的最末元素+1即可

然后用sun记录0出现的次数,减少重复更新

因为0可以变成负数,所以初始化d[0] = -inf

不多说,代码很简单 直接看代码

code:

#define mem(a,x) memset(a,x,sizeof(a))
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf = 1<<29;

/*
Description: 最长上升子序列

定义d[k]:长度为k的上升序列最末元素(终点元素)
//注意d中元素是单调递增的
初始化:len = 1,d[1]=a[1],
然后对于a[i]:
if a[i] > d[len]
len++,d[len] = a[i]
else
from d[1] to d[len]找到一个j
满足 d[j-1]<a[i]<d[j]
更新d[j] = a[i]
*/
const int NN = 100007;
int d[NN],a[NN];
int main()
{
int n;
int kas = 0;
int T;scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int i = 1;i <= n;++i)
{
scanf("%d",a+i);
}
int len = 1;
d[0] = -inf;
d[1] = a[1];
int sun = 0;
for (int i = 2;i <= n;++i)
{
if (a[i] > d[len])
{
d[++len] = a[i];
}
else if (a[i] == 0)//唯一与裸的最长上升子序列不同的地方
{
for (int j = len;j >= sun;--j)
{
d[j+1] = d[j]+1;
}
len++;
sun++;
}
else
{
int p = lower_bound(d,d+len,a[i]) - d;
d[p] = a[i];
}
}
printf("Case #%d: %d\n",++kas,len);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp hdu 多校