• LIS【p1704】寻找最优美做题曲线


    Description

    洛谷OJ刷题有个有趣的评测功能,就是系统自动绘制出用户的“做题曲线”。所谓做题曲线就是一条曲线,或者说是折线,是这样定义的:假设某用户在第b[i]天AC了c[i]道题,并且b[i]严格递增,那么该用户的做题曲线就是平面上点(i,c[i])依次连出的一条折线。比如你在第1天做了3道题,第3天做了4道题,第6天做了1道题,那么你在前6天的做题曲线就是从点(1,3)到点(2,4)到点(3,1)的连续折线。

    nodgd同学可以预测出自己未来N天每条能够AC题目的数量,同时有一个很无趣的爱好,就是单调递增,nodgd强迫自己的做题曲线保持严格的单调递增。但是出于某些原因,nodgd在某些日子(共有K天)必须刷题,而且刷题数量一定是预计的数量(体现nodgd的神预测)。nodgd同学想知道,在这样的情况下,自己最多有多少天可以刷题,不过nodgd同学还有大量的数学竞赛题、物理竞赛题、英语竞赛题、美术竞赛题、体育竞赛题……要做,就拜托你来帮他算算了。

    Input

    第一行两个正整数,N和K,表示nodgd预测了未来N天每天做题的数量,其中K天必须刷题。

    第二行K个正整数p[i],表示第p[i]天必须刷题(1<=p[i]<=N,保证每个p[i]不同)。

    第三行N个正整数c[i],表示在第i天nodgd可以AC的题目数量必须是c[i]。

    Output

    一行。

    如果能找到严格递增的做题曲线:一个正整数,表示nodgd最多有多少天可以刷题。

    如果找不到严格递增的做题曲线:直接输出“impossible”(不加引号,全是小写字母)。

    woc,渣题。

    首先需要明确的是,我们需要维护最长上升子序列.就像我的刷题记录 qwq

    题目要求必须选一些位置,这些位置是必须选的.

    所以我们需要考虑的是这些位置,两两之间的位置的合法性.

    例如这样:

      蓝色部分必选.

    中间部分均不合法.我们标记一下即可。

    由于(p_i)不连续,所以我们需要(Sort).

    但是我们还需要判断左右两端是否合法.(这个坑死了.

    小声bb

    我们已经筛去了不合法的位置,所以合法位置一定是严格递增的。

    又因为我们必选位置一定会是其中的一员,因此这些必选位置一定会被选.

    代码

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define R register
    using namespace std;
    inline void in(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    int n,m,stk[5000008],top,a[5000008];
    int flg[5000008];
    bool vis[5000008];
    int main()
    {
    	in(n),in(m);stk[0]=-1;
    	for(R int i=1,x;i<=m;i++)in(flg[i]);
    	for(R int i=1;i<=n;i++)in(a[i]),vis[i]=true;
    	sort(flg+1,flg+m+1);
    	for(R int i=1;i<m;i++)
    	{
    		if(a[flg[i]]>=a[flg[i+1]])
    		{
    			puts("impossible");
    			return 0;
    		}
    		for(R int j=flg[i]+1;j<flg[i+1];j++)
    			if(a[j]<=a[flg[i]] or a[j]>=a[flg[i+1]])
    				vis[j]=false;
    	}
    	for(R int i=1;i<flg[1];i++)
    		if(a[i]>=a[flg[1]])vis[i]=false;
    	for(R int i=flg[m]+1;i<=n;i++)
    		if(a[i]<=a[flg[m]])vis[i]=false;
    	for(R int i=1;i<=n;i++)
    	{
    		if(!vis[i])continue;
    		if(a[i]>stk[top])
    			stk[++top]=a[i];
    		else
    		{
    			int l=1,r=top;
    			while(l<=r)
    			{
    				int mid=(l+r)>>1;
    				if(stk[mid]>a[i])r=mid-1;
    				else l=mid+1;
    			}
    			stk[l]=a[i];
    		}
    	}
    	printf("%d",top);
    }
    
  • 相关阅读:
    创建窗口
    文件映射
    匿名管道
    MFC之进度条CProgressCtrl
    跨进程使用句柄和文件操作
    redis安装配置
    git全部操作
    idea中Entity实体中报错:cannot resolve column/table/
    Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon
    sql操作
  • 原文地址:https://www.cnblogs.com/-guz/p/9774422.html
Copyright © 2020-2023  润新知