HDU 5773 The All-purpose Zero 16多校4 贪心 LCA

1 篇文章 0 订阅
1 篇文章 0 订阅

题意:给一个有n(n<=100000)个数字的序列,其中要么是0要么是正整数,0可以变成任意整数,问该序列的最长上升子序列。
比赛的时候被这题卡了三个小时,貌似因为数据水,有的人错误的代码都过了,自己真的菜啊…………

思路:贪心的思路应该是基于这个结论:lca不一定包含所有0,但是所有0组成的某个序列一定是lca其中的一个。大题证明思路:如果有一个lca不含所有的0,那么我们可以把这个lca中靠近原序列中的0的某个数换成0,数次这样操作,这个lca就变成了包含所有0的lca。

那么正如题解说的,可以把所有的0拿出来,每个非0的数减去前面出现的0的个数,然后对这些数计算lca,加上0的总数就ok了,这样得到的lca包含了所有0,且保证了其他非0数组成的lca最长

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define lowbit(x) (x&(-x))
typedef long long LL;
inline void fre1(){freopen("1010.in","r",stdin);/*freopen("output.txt","w",stdout);*/}
inline void fre2(){fclose(stdin);/*fclose(stdout);*/}
const int MAXN=100000+5;
const double EPS=1e-8;
int n,x,tot,sum;
int a[MAXN],dp[MAXN];

int main()
{
    int T,kase=0;
    scanf("%d",&T);
    while(T--){
        bool flag=false;
        scanf("%d",&n);
        tot=0,sum=0;
        for(int i=1;i<=n;++i){
            scanf("%d",&x);
            if(x) a[++tot]=x-sum,flag=true;
            else ++sum;
        }
        MS(dp,0);
        dp[1]=a[1];
        int ans=1;
        for(int i=2;i<=tot;++i){
            int p=lower_bound(dp+1,dp+1+ans,a[i])-dp;
            dp[p]=a[i];
            ans=max(ans,p);
        }
        if(!flag) ans=0;
        printf("Case #%d: %d\n",++kase,ans+sum);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值