codeforces1437 E. Make It Increasing——最长上升子序列
生活随笔
收集整理的這篇文章主要介紹了
codeforces1437 E. Make It Increasing——最长上升子序列
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
E. Make It Increasing
首先讓ai=ai?ia_i=a_i-iai?=ai??i這樣可以是嚴格單增變成單調增。
參考官方題解
首先不難得出如果我們根據不同修改的位置分割成若干段,那么若干段是互不影響的,我們只需要求出每一個若干段修改次數的最小值。
如果當前考慮l~r這一段,這里l和r都是不能修改的位置,我們要使得al≤al+1→r?1≤ara_l\leq a_{l+1\to r-1}\leq a_ral?≤al+1→r?1?≤ar?,對于原來不在此范圍內的數一定需要修改,所以只需要考慮在此范圍內的數如何修改的最少!實際上是選擇最長的上升子序列,剩下的修改即可。而最長上升子序列我們可以O(nlogn)解決。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<set> #include<map> #include<cmath> #include<stack> #include<queue> #include<random> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<unordered_map> #include<unordered_set> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N=500010; int a[N],b[N],n,k; int main() {IO;int T=1;//cin>>T;while(T--){cin>>n>>k;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++) cin>>b[i];a[0]=-1e9,a[n+1]=2e9;for(int i=0;i<=n+1;i++) a[i]-=i;b[k+1]=n+1;b[0]=0;bool ok=1;int res=0;for(int i=0;i<=k;i++){int l=b[i],r=b[i+1];if(a[l]>a[r]){ok=0;break;}vector<int> lis;for(int j=l+1;j<r;j++)if(a[l]<=a[j]&&a[j]<=a[r]){auto pos=upper_bound(lis.begin(),lis.end(),a[j]);if (pos==lis.end()) lis.push_back(a[j]);else *pos=a[j];//這里會修改值}res+=(r-l-1)-lis.size();}if(!ok) res=-1;cout<<res<<'\n';}return 0; }反思:md我知道那個小trick使得嚴格變成非嚴格,但是還是沒能運用,還是見的太少,沒運用這個小trick導致我的判斷不合法時尤為困難。
題解中的最長上升子序列代碼好簡潔,學習了!
貪心,考慮當前的數,那么替換第一個大于它的數并不影響原來維護序列的單調性,而且答案不會更差!
要加油哦~
總結
以上是生活随笔為你收集整理的codeforces1437 E. Make It Increasing——最长上升子序列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 澎湃OS显示仍基于安卓 业内人士:国产厂
- 下一篇: 2020 China Collegiat