Codeforces Round #462 (Div. 2) D-A Twisty Movement (枚举)
【题意】
给n, n个数只有1,2组成, 翻转【L,R】后问最长不降序列长度;
【思路】
只有1,2组成,最长是1,2 那么 第一个2 出现的位置 P 【L,P】翻转使得后面的2的数目减少
【P,R】翻转使得 前面1 的数目增加
前面1的前缀和,后面2的后缀和,, 枚举p,然后 枚举 L,R 的位置, 使得 【1,L】 1的数目 + 【L,P】2的数目
【R,N】 2的数目 + 【P,R】 1的数目 之和 最大
【代码】
#include <iostream> #include <bits/stdc++.h> #include <stdio.h> #define mem(a,b) memset(a,b,sizeof(a)) const int MAXN=1e5+5; const int INF=0x3f3f3f3f; #define SHUT ios_base::sync_with_stdio(false); cout.setf(ios::fixed); cout.precision(20); cout.tie(nullptr); cin.tie(nullptr); using namespace std; int a[MAXN]; int pre[MAXN]; int aft[MAXN]; int main() { SHUT; int n; cin>>n; mem(a,0); for(int i=1;i<=n;i++) cin>>a[i]; mem(pre,0); mem(aft,0); for(int i=1,j=n;i<=n;i++,j--) { pre[i]=pre[i-1]+(a[i]==1); aft[j]=aft[j+1]+(a[j]==2); } int ans=-INF; for(int i=1;i<=n+1;i++) { int t1=0,t2=0; for(int j=1;j<=i;j++) t1=max(t1,pre[j-1]+aft[j]-aft[i]); for(int j=i;j<=n+1;j++) t2=max(t2,aft[j]+pre[j-1]-pre[i-1]); ans=max(ans,t1+t2); } cout<<ans<<endl; return 0; }
123
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!