1. 程式人生 > >Codeforces 934C - A Twisty Movement

Codeforces 934C - A Twisty Movement

std eof div mov sync force tdi its fine

934C - A Twisty Movement

思路:dp

很容易想到要預處理出1的前綴和pre[i]和2的後綴和suf[i]

然後枚舉區間,對於每個區間如果能求出最長遞減序列的長度,那麽就能更新答案了

這個用dp求

狀態:

dp[i][j][0]表示i--j區間以2結尾的最長遞減序列長度,很明顯這個序列全為2,所以也就是i--j區間2的個數

dp[i][j][1]表示i--j區間以1結尾的最長遞減序列長度

狀態轉移:

dp[i][j][0]=dp[i][j-1][0]+(a[j]==2)
dp[i][j][1]=max(dp[i][j-1][0],dp[i][j-1][1])+(a[j]==1)

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=2e3+5;
int a[N];
int pre[N];
int suf[N];
int dp[N][N][2];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin
>>n; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++)pre[i]=pre[i-1]+(a[i]==1); for(int i=n;i>=1;i--)suf[i]=suf[i+1]+(a[i]==2); int ans=0; for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ dp[i][j][0]=dp[i][j-1][0]+(a[j]==2); dp[i][j][
1]=max(dp[i][j-1][0],dp[i][j-1][1])+(a[j]==1); ans=max(ans,pre[i-1]+suf[j+1]+dp[i][j][0]); ans=max(ans,pre[i-1]+suf[j+1]+dp[i][j][1]); } } cout<<ans<<endl; return 0; }

Codeforces 934C - A Twisty Movement