您的位置:首页 > 其它

hdu 5773 (The All-purpose Zero)

2016-08-12 08:45 218 查看
The All-purpose Zero

 

[align=left]Problem Description[/align]
?? 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.
 

[align=left]Input[/align]
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.

 

[align=left]Output[/align]
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.
 

[align=left]Sample Input[/align]

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

 

[align=left]Sample Output[/align]

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.

 题意:求最长上升子序列,0可以变成任意数。
题解:LIS变形,一直没想到怎么处理中间的0,其实可以先去掉0,求出上升子序列,然后加上0的个数lower_bound(s,t,val),返回第一个大于等于val的数的位置,upper_bound(s,t,val)返回第一个大于val的数的位置,两者相减可以得到序列中k的个数。
#include<cstdio>
#include<algorithm>
#define INF 0x3f3f3f3f
#define M 100100
using namespace std;
int s[M];
int dp[M];
int main(){
int t,n,i,sum,ans;
int cas=1;
scanf ("%d",&t);
while (t--){
sum=0;
ans=0;
scanf ("%d",&n);
for (i=0;i<n;i++){
scanf ("%d",&s[i]);

}
fill(dp,dp+n,INF);
for (i=0;i<n;i++){
if (s[i]==0){
ans++;
}
else
*lower_bound(dp,dp+n,s[i]-ans)=s[i]-ans;//去除0
}
sum=lower_bound(dp,dp+n,INF)-dp;
sort (s,s+n);
sum+=upper_bound(s,s+n,0)-lower_bound(s,s+n,0);//可以直接sum+=ans;
printf ("Case #%d: %d\n",cas++,sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: