zoukankan      html  css  js  c++  java
  • 题解 CF1437E 【Make It Increasing】

    题目链接

    Solution CF1437E Make It Increasing

    题目大意:给定一个序列,以及一些不能被修改的位置。问最少修改几个数可以使得序列严格单调递增。

    dp


    分析:

    首先经典结论,把每个数减去它的下标,这样我们就只需要使得序列单调不降就可以了,元素可以相同更方便一些。

    最少修改几个数,可以转化为,我们要在序列中选取一个最长不下降子序列,修改其他位置的值。而那些不能被修改的位置,就是我们必须选入子序列的位置。

    这样我们沿用 (nlogn) 的经典做法,只不过稍加改动。设上一个钦定被选择的位置为 (pre),下一个位置为 (nxt),那么当前的位置 (p) 可能被选入子序列,当且仅当 (val[pre] leq val[p] leq val[nxt])

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #pragma GCC optmize(2)
    using namespace std;
    typedef long long ll;
    constexpr int maxn = 5e5 + 100,inf = 0x7fffffff;
    struct IO{//-std=c++11,with cstdio and cctype
    	private:
    		static constexpr int ibufsiz = 1 << 20;
    		char ibuf[ibufsiz + 1],*inow = ibuf,*ied = ibuf;
    		static constexpr int obufsiz = 1 << 20;
    		char obuf[obufsiz + 1],*onow = obuf;
    		const char *oed = obuf + obufsiz;
    	public:
    		inline char getchar(){
    			#ifndef ONLINE_JUDGE
    				return ::getchar();
    			#else
    				if(inow == ied){
    					ied = ibuf + sizeof(char) * fread(ibuf,sizeof(char),ibufsiz,stdin);
    					*ied = '';
    					inow = ibuf;
    				}
    				return *inow++;
    			#endif
    		}
    		template<typename T>
    		inline void read(T &x){
    			static bool flg;flg = 0;
    			x = 0;char c = getchar();
    			while(!isdigit(c))flg = c == '-' ? 1 : flg,c = getchar();
    			while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    			if(flg)x = -x;
    		}
    		template <typename T,typename ...Y>
    		inline void read(T &x,Y&... X){read(x);read(X...);}
    		inline int readi(){static int res;read(res);return res;}
    		inline long long readll(){static long long res;read(res);return res;}
    		
    		inline void flush(){
    			fwrite(obuf,sizeof(char),onow - obuf,stdout);
    			fflush(stdout);
    			onow = obuf;
    		}
    		inline void putchar(char c){
    			#ifndef ONLINE_JUDGE
    				::putchar(c);
    			#else
    				*onow++ = c;
    				if(onow == oed){
    					fwrite(obuf,sizeof(char),obufsiz,stdout);
    					onow = obuf;
    				}
    			#endif
    		}
    		template <typename T>
    		inline void write(T x,char split = ''){
    			static unsigned char buf[64];
    			if(x < 0)putchar('-'),x = -x;
    			int p = 0;
    			do{
    				buf[++p] = x % 10;
    				x /= 10;
    			}while(x);
    			for(int i = p;i >= 1;i--)putchar(buf[i] + '0');
    			if(split != '')putchar(split);
    		}
    		inline void lf(){putchar('
    ');}
    		~IO(){
    			fwrite(obuf,sizeof(char),onow - obuf,stdout);
    		}
    }io;
    template <typename A,typename B>
    inline void chkmin(A &x,const B &y){if(y < x)x = y;}
    template <typename A,typename B>
    inline void chkmax(A &x,const B &y){if(y > x)x = y;}
    
    int val[maxn],g[maxn],ans;
    vector<int> pos;
    int main(){
    	const int n = io.readi(),k = io.readi();
    	for(int i = 1;i <= n;i++)io.read(val[i]),val[i] -= i;
    	pos.push_back(0);
    	for(int i = 1;i <= k;i++)pos.push_back(io.readi());
    	for(unsigned int i = 2;i < pos.size();i++)
    		if(val[pos[i - 1]] > val[pos[i]])return io.write(-1,'
    '),0;
    	pos.push_back(n + 1);
    	val[0] = -inf;
    	val[n + 1] = inf;
    	memset(g,0x7f,sizeof(g));
    	for(int i = 1;i <= n;i++){
    		int nxt = *upper_bound(pos.begin(),pos.end(),i);
    		int pre = *prev(lower_bound(pos.begin(),pos.end(),i));
    		if(val[i] > val[nxt] || val[i] < val[pre])continue;
    		int p = upper_bound(g + 1,g + n,val[i]) - g;
    		if(nxt == n + 1)chkmax(ans,p);
    		g[p] = val[i];
    	}
    	return io.write(n - ans,'
    '),0;
    }
    
  • 相关阅读:
    POJ2253Frogger
    POJ3982The Fibonacci sequence
    POJ3259Wormholes
    POJ1062Expensive dowry
    POJ1860Currency Exchange
    POJ1789Truck History .
    POJ2602Superlong sums
    POJ1125Stockbroker Grapevine
    POJ2485Highways
    POJ2240Arbitrage
  • 原文地址:https://www.cnblogs.com/colazcy/p/14076136.html
Copyright © 2011-2022 走看看