zoukankan      html  css  js  c++  java
  • codeforce 462DIV2 C题

    题意

      给出一个只含有1和2的序列,有n个元素,可以选择一段区间进行翻转操作,求再反转后的最大非递减子序列的长度

    分析

     太菜了只想出了N^2的做法。
    序列只有1和2,那么每个非递减子序列都会有一个分界点,在分界点前是1以后是2。观察可以发现,只有当翻转的区间包含这个分界点的时候,这个分界点的非递减子序列的长度才会发生变化。定义dp[i][j]为反转区间i,j,且分界点在区间i,j的最长非递减子序列的长度。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 using namespace std;
     6 const int maxn=2000+50;
     7 int n;
     8 int a[maxn];
     9 int sum1[maxn],sum2[maxn];
    10 int dp[maxn][maxn];
    11 int main(){
    12     scanf("%d",&n);
    13     sum1[0]=sum1[0]=0;
    14     for(int i=1;i<=n;i++){
    15         scanf("%d",&a[i]);
    16         if(a[i]==1){sum1[i]=sum1[i-1]+1;sum2[i]=sum2[i-1];}
    17         if(a[i]==2){sum2[i]=sum2[i-1]+1;sum1[i]=sum1[i-1];}
    18     }
    19     int ans=0;
    20     for(int i=0;i<=n;i++)ans=max(ans,sum1[i]+sum2[n]-sum2[i]);
    21     for(int i=1;i<=n;i++)
    22         dp[i][i]=sum1[i]+sum2[n]-sum2[i];
    23       for(int len=2;len<=n;len++){
    24             for(int i=1;i<=n-len+1;i++){
    25             int j=i+len-1;
    26             if(a[j]==2&&a[i]==1){
    27                 if(len>2)dp[i][j]=dp[i+1][j-1]-2;
    28                 else if(len<=2)dp[i][j]=dp[i][j-1]-2;
    29                 }
    30             else if(a[j]==1&&a[i]==2){
    31                 if(len>2)dp[i][j]=dp[i+1][j-1]+2;
    32                 else if(len<=2)dp[i][j]=dp[i][j-1]+2;
    33                 }
    34             else if(a[i]==a[j]){
    35                 if(len<=2)dp[i][j]=dp[i][j-1];
    36                 else
    37                 dp[i][j]=dp[i+1][j-1];
    38             }
    39             dp[i][j]=max(dp[i][j],max(sum1[j]+sum2[n]-sum2[j],sum1[i-1]+sum2[n]-sum2[i-1]+(a[j]==1)));
    40             }
    41       }
    42     for(int i=1;i<=n;i++){
    43         for(int j=i;j<=n;j++){
    44            // cout<<i<<"---->"<<j<<" "<<dp[i][j]<<endl;
    45             ans=max(ans,dp[i][j]);
    46         }
    47     }
    48     printf("%d",ans);
    49 return 0;
    50 }
    View Code

    这个题官方题解给出了O(n)的做法orzzzz

  • 相关阅读:
    Activity与Fragment间的通信
    Activity生命周期.lanchMode.保存状态
    网络知识
    Android内存优化(使用SparseArray和ArrayMap代替HashMap)
    进程/线程死锁产生的原因以及如何避免死锁
    Android UI框架基本概念
    android在线源码
    y音频学习
    给 Android 开发者的 RxJava 详解
    设计模式之观察者模式
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8825115.html
Copyright © 2011-2022 走看看