1. 程式人生 > >hdu 5256 序列變換 求最少改變次數使序列變為遞增 最長不下降子序列

hdu 5256 序列變換 求最少改變次數使序列變為遞增 最長不下降子序列

題意:我們有一個數列A1,A2…An,你現在要求修改數量最少的元素,使得這個數列嚴格遞增。其中無論是修改前還是修改後,每個元素都必須是整數。
請輸出最少需要修改多少個元素。

對於任意兩個數A[i],A[j](i>j) 如果滿足A[i]A[j]ij可以使得[i,j]區間內的數都是可修改為遞增的,可以將上面那個式子轉換為A[i]iA[j]j,這樣子,我們可以先求出新的數字A[i]i的最長的不需要改變的長度,也就是最長不下降子序列,這個序列中的數不需要改變,答案為n-最長不下降子序列長度

//author: CHC
//First Edit Time:  2015-09-05 12:55
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <limits> using namespace std; typedef long long LL; const
int MAXN=1e+5 + 1000; const int INF = numeric_limits<int>::max(); const LL LL_INF= numeric_limits<LL>::max(); int s[MAXN],A[MAXN],C[MAXN],n; int main() { int t,cas=0; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d"
,&A[i]); s[i]=A[i]-i; } int k=0; C[k++]=s[1]; for(int i=2;i<=n;i++){ if(C[k-1]<=s[i])C[k++]=s[i]; else { int pos=upper_bound(C,C+k,s[i])-C; C[pos]=s[i]; } } printf("Case #%d:\n%d\n",++cas,n-k); } return 0; }