这次的两题都是求连续的递增序列,我主要是用求最长连续子序列的方法解决的,核心(int po=lower_bound(ans,ans+len,b[i])-ans;),理解这句代码,节能解决一类题
5773The All-purpose Zero
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[100001],ans[100001],b[100001];
int main()
{
int i,t,n,zero,count,len,h=1,flag;
scanf("%d",&t);
while(t--)
{
zero=0;
count=0;
flag=1;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(b,0,sizeof(b));
memset(ans,0,sizeof(ans));
for(i=1;i<=n;i++)
{
if(a[i]==0) zero++;
else
{
flag=0;
b[count++]=a[i]-zero;
}
}
ans[0]=b[0];
len=1;
for(i=1;i<count;i++)
{
if(ans[len-1]<b[i]) ans[len++]=b[i];
else
{
int po=lower_bound(ans,ans+len,b[i])-ans;
ans[po]=b[i];
}
}
if(flag==1) len=0;
printf("Case #%d: %d\n",h++,len+zero);
}
return 0;
}
1257最少拦截次数
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100001],b[100001];
int main()
{
int n,i,count;
while(scanf("%d",&n)!=EOF)
{
count=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
b[0]=a[0];
int len=1;
for(i=1;i<=n;i++)
{
if(b[len-1]<a[i]) b[len++]=a[i];
else
{
int pos = lower_bound(b,b+len,a[i])-b;
b[pos] = a[i];
}
}
printf("%d\n",len-1);
}
}