CF 1437E Make It Increasing 題解


題目大意

給你一個數列 \(a\) ,一個集合 \(b\) , 對於每個\(b\) 中的元素\(x\)\(a_x\) 不能修改,其他都可以修改,問最少多少次可以將\(a\) 修改為嚴格單調遞增的。如果不存在,輸出 \(-1\)

思路

我們先考慮不存在的情況,一定是存在\(x,y\in b,x < y\) ,\(a_y-a_x < y-x\) , 這樣無法在 \(a_x,a_y\) 中任意修改滿足嚴格單調遞增。


那么接下來考慮最小的修改次數。

加入我們沒有修改限制呢?

那么就是一個經典的\(DP\) 問題了。

我們將原數組變形,讓\(a_x = a_x -x\),然后跑一遍最長不下降子序列就行了(用 \(nlogn\) 的算法),答案就是 \(n-\)最長不下降子序列長度了。

但是有限制,我們先考慮一下沒有限制的代碼。

for(int i = 1;i <= n;i++) a[i] -= i;
for(int i = 1;i <= n;i++){
	if(e == 0 || a[i] >= l[e]) {
	    l[++e] = a[i];
	}
	else{
	    int p = upper_bound(l+1,l+e+1,a[i])-l;
	    l[p] = a[i];
	}
}//e : l 數組的末尾標號。

這樣的代碼會在遍歷 \(a\) 數組時不斷更新自己的一個假想的答案序列,使它每個值盡可能的小,然后容下一個新的值,使答案最大。

在判過是否滿足后,\(\forall x\in b\)\(a_x\) 一定也可以在處理后形成一個不下降子序列,我們要保證不修改它們,就要讓它們處於這個假想的答案序列中,於是我們可以加上幾行:

//lasb ,上一個不能修改的位置在我們當前維護的假想答案序列中的位置。
//ban[i] , a[i] 是否禁止修改。
for(int i = 1;i <= n;i++){
	if(e == 0 || a[i] >= l[e]) {
	    l[++e] = a[i];
	    if(ban[i]) lasb = e;
	}
	else{
	    int p = upper_bound(l+1,l+e+1,a[i])-l;
	    if(p <= lasb) continue;//如果我們要更改的位置小於上一個不能修改的位置,那么就不能更改假想的答案序列
	    l[p] = a[i];
	    if(ban[i]) lasb = p,e = p;//答案序列p后面的位置都不滿足條件,因為它們不能大於這個不能修改的位置,因此對我們要的最長不下降子序列不能產生貢獻。
	}
}

魔改一下這個算法后,就可以\(AC\) 了。(具體理解見代碼,可以結合一下\(nlogn\)的最長不下降子序列的算法)

Code

#define re(x) read(x)

const int MAXN = 1e6+10;

int n,k;
int a[MAXN],l[MAXN],e,b[MAXN],lasb=0;
bool ban[MAXN];

int main (){
    re(n);re(k);
    for(int i = 1;i <= n;i++) re(a[i]);
    for(int i = 1;i <= k;i++) re(b[i]),ban[b[i]]=1;
    sort(b+1,b+k+1);
    for(int i = 2;i <= k;i++)
		if(a[b[i-1]] - b[i-1] > a[b[i]] - b[i]){
	    	return puts("-1"),0;
		}
    for(int i = 1;i <= n;i++) a[i] -= i;
    for(int i = 1;i <= n;i++){
		if(e == 0 || a[i] >= l[e]) {
	    	l[++e] = a[i];
	    	if(ban[i]) lasb = e;
		}
		else{
	    	int p = upper_bound(l+1,l+e+1,a[i])-l;
	    	if(p <= lasb) continue;
	    	l[p] = a[i];
	    	if(ban[i]) lasb = p,e = p;
		}
    }
    printf("%d",n-e);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM