您的位置:首页 > 其它

[bzoj4282]慎二的随机数列

2016-10-12 11:28 267 查看
题目大意:求缺损了部分数的lis的最大可能值 n<=100000

大概是这样的

首先我们显然可以发现 我们要尽量将不知道的数塞进lis里 这样一定是最优的

因此我们可以将不知道的数去掉之后求lis 然后再把可能的数加进去

那我们怎么统计可能的数以及保证他一定能塞进去呢?

用一个类似前缀和的东西 首先你对不知道的数的情况求一个类似前缀和的东西 然后用每个数减掉他再求 最后再加上能加的不知道的数的个数

由于n很大所以要用nlogn求lis

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<iostream>
#include<algorithm>
#include<stack>
#include<cstring>
#include<set>
#include<map>
#include<iomanip>
using namespace std;
const int INF = 0x7f7f7f7f;
const double pi = acos(-1.0);
inline int init()
{
int now=0,ju=1;char c;bool flag=false;
while(1)
{
c=getchar();
if(c=='-')ju=-1;
else if(c>='0'&&c<='9')
{
now=now*10+c-'0';
flag=true;
}
else if(flag)return now*ju;
}
}
int array[100001];
int dp[100001];
int len=0;
int a[100001],n;
int sumzero[100001];
int c[100001];
int main()
{
char str[10];
n=init();
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
if(str[1]=='K')
{
a[i]=init();
sumzero[i]=sumzero[i-1];
if(len==0)
{
dp[++len]=a[i]-sumzero[i];
}
}
else
{
a[i]=0;
sumzero[i]=sumzero[i-1]+1;
}
c[i]=a[i]-sumzero[i];
}
int ans[100001];
ans[1]=1;
int pos;
for(int i=2;i<=n;i++)
{
if(a[i]==0)
{
ans[i]=len+sumzero[i];
continue;
}
if(c[i]>dp[len])
{
dp[++len]=c[i];
}
else
{
pos=lower_bound(dp+1,dp+1+len,c[i])-dp;
dp[pos]=c[i];
}
ans[i]=len+sumzero[i];
}
sort(ans+1,ans+1+n);
printf("%d\n",ans
);
return 0;
}

附带一份同学的 虽然题目并不相同 但是基本上是一样的用作理解

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int a[maxn];
int f[maxn];
int b[maxn];
int n;
int mr;
int find(int l,int r,int val)
{
int pos=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(b[mid]<val)
{
pos=mid;
l=mid+1;
}
else r=mid-1;
}
return pos;
}
int main()
{
//freopen("lis.in","r",stdin);
//freopen("lis.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(b,63,sizeof b);
b[0]=-0x3f3f3f3f;
for(int i=1;i<=n;i++)
{
if(a[i]==0)
{
b[mr+1]=b[mr]+1;
for(int j=mr;j>=1;j--)
if(b[j-1]+1<b[j])
b[j]=b[j-1]+1;
mr++;
f[i]=mr;
}
else
{
int x=find(1,i-1,a[i]);
f[i]=x+1;
b[x+1]=min(b[x+1],a[i]);
if(f[i]>mr) mr=f[i];
}
}
printf("%d",mr);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: