zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    LeetCode OJ 107. Binary Tree Level Order Traversal II
    LeetCode OJ 116. Populating Next Right Pointers in Each Node
    LeetCode OJ 108. Convert Sorted Array to Binary Search Tree
    LeetCode OJ 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode OJ 98. Validate Binary Search Tree
    老程序员解Bug的通用套路
    转载 四年努力,梦归阿里,和大家聊聊成长感悟
    转载面试感悟----一名3年工作经验的程序员应该具备的技能
    Web Service和Servlet的区别
    关于spring xml文件中的xmlns,xsi:schemaLocation
  • 原文地址:https://www.cnblogs.com/-guz/p/9774422.html
Copyright © 2011-2022 走看看