您的位置:首页 > 其它

HDU - 5773 - The All-purpose Zero 【必做题目之LIS+++贪贪贪贪心】

2017-10-04 14:58 483 查看

The All-purpose Zero

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 2455 Accepted Submission(s): 1114

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

Recommend

wange2014

题意: 你没有看错,??是一个人名,不是什么鬼符号,姑且叫小问吧,小问有一个长度为n的数列,其中0可以变成任意整数(可以为负数哦),但不可以所有的0变成一个数,让你找一个最长上升子序列的长度。

分析:一开始做的时候方向错了,是先把最长子序列找出来,再依次的判断0是否可以插入,最后再加起来,发现一个样例不对,比如:1 2 0 0 0 0 4 5,错误在于最长的序列已经固定了,然而正解不是这样的,是所有的0都可以用到,然后贪心的先把0的空间预留出来,关键是怎么预留呢,看了正解后,虽然还是有点不懂,但是找不到反例:( 具体做法:把每一个非零数减去前面零的个数,等真正理解了再续吧~~~。

反思:这里b数组(就是存储LIS的数组)有个技巧,先设置一个最小数放在第一个,就可以保证从第一个开始了(这里不好理解,反正只要理解了LIS的真正做法,就知道了,都是从第二个数才开始),还有一个坑点,就是如果1前面有一个零的话,剪掉的话就是0了,所以,还得预处理一下之前零的位置,这里我用了h数组来处理

参考代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7,INF = 10000000;
int a[maxn],b[maxn],h[maxn];
int main(){
int T;cin>>T;
for(int TT = 1;TT <= T;TT++){
memset(h,0,sizeof(h));   //注意这个
cout<<"Case #"<<TT<<": ";
int n;cin>>n;
int cnt = 0;
for(int i = 1;i <= n;i++){
cin>>a[i];
if(a[i] == 0) {cnt++;h[i] = 1;}
else a[i] -= cnt;
}
if(cnt == n){cout<<n<<endl;continue;}
int len = 0;
b[0] = -INF;
for(int i = 1;i <= n;i++){
if(h[i])continue;
if(a[i] > b[len]) b[++len] = a[i];
else {
int t = lower_bound(b,b+len,a[i]) - b;
b[t] = a[i];
}
}
cout<<cnt+len<<endl;
}
return 0;
}


如有错误或遗漏,请私聊下UP,ths
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: