zoukankan      html  css  js  c++  java
  • bzoj4758: [Usaco2017 Jan]Subsequence Reversal(区间dp)

    4758: [Usaco2017 Jan]Subsequence Reversal

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 76  Solved: 52
    [Submit][Status][Discuss]

    Description

    Farmer John is arranging his NN cows in a line to take a photo (1≤N≤50). The height of the iith co
    w in sequence is a(i), and Farmer John thinks it would make for an aesthetically pleasing photo if t
    he cow lineup has a large increasing subsequence of cows by height.To recall, a subsequence is a sub
    set a(i1),a(i2),…,a(ik)) of elements from the cow sequence, found at some series of indices i1<i2<
    …<ik, We say the subsequence is increasing if a(i1)≤a(i2)≤…≤a(ik).FJ would like there to be a l
    ong increasing subsequence within his ordering of the cows. In order to ensure this, he allows himse
    lf initially to choose any subsequence and reverse its elements.
     
    For example, if we had the list
     
    1 6 2 3 4 3 5 3 4
    We can reverse the chosen elements
     
    1 6 2 3 4 3 5 3 4
      ^         ^ ^ ^
    to get
     
    1 4 2 3 4 3 3 5 6
      ^         ^ ^ ^
    Observe how the subsequence being reversed ends up using the same indices as it initially occupied, 
    leaving the other elements unchanged.Please find the maximum possible length of an increasing subseq
    uence, given that you can choose to reverse an arbitrary subsequence once.
    给定一个长度为N的序列,允许翻转一个子序列,求最长不下降子序列长度。n和数字都<=50
     

     

    Input

    The first line of input contains N. The remaining N lines contain a(1)…a(N),
    each an integer in the range 1…50.
     

     

    Output

    Output the number of elements that can possibly form a longest increasing subsequence 
    after reversing the contents of at most one subsequence.
     

     

    Sample Input

    9
    1
    2
    3
    9
    5
    6
    8
    7
    4

    Sample Output

    9

    HINT

     

    Source

    Platinum

    /*
    感觉这道题没完全懂
    开始设状态毫无思路,只知道可能很多维......
    想到可能是道区间dp,emm那就考虑一段区间[l,r]怎么维护里面交换那些数呢?
    发现可以用值域这个东西把数给框住。又,反转区间肯定是越靠右的反转到越靠左位置。
    那么由小区间推大区间时,只需要判断端点处包不包括在这一次的交换中即可。 
    所以可dp[i][j][L][R]为区间[i,j]里面min(ak) >= L, max(ak) <= R时,反转一次的最长不下降子序列。
    转移见代码。 
    */
    #include<bits/stdc++.h>
    
    #define N 51
    
    using namespace std;
    int n,a[N],ans;
    int dp[N][N][N][N];
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
      n=read();
      for(int i=1; i <= n; ++i) a[i]=read(),dp[i][i][a[i]][a[i]]=1;
      
      for(int len=2; len <= n; ++len) for(int i=1; i+len-1 <= n; ++i)//当前区间 
          {
                   int j=i+len-1;
                for(int l=1; l <= 50; ++l) for(int L=1; L+l-1 <= 50; ++L)//当前值域 
                {
                      int R=L+l-1;
                      ans=dp[i][j][L][R];
                      ans=max(ans,max(dp[i+1][j][L][R],dp[i][j-1][L][R]));
                      ans=max(ans,max(dp[i][j][L+1][R],dp[i][j][L][R-1]));
                      dp[i][j][L][R]=ans;
                      //copy小区间的答案 
                      dp[i][j][min(L,a[i])][R]=max(dp[i][j][min(L,a[i])][R],dp[i+1][j][L][R]+(a[i] <= L));
                      dp[i][j][L][max(R,a[j])]=max(dp[i][j][L][max(R,a[j])],dp[i][j-1][L][R]+(a[j] >= R));
                      dp[i][j][min(L,a[i])][max(R,a[j])]=max(dp[i][j][min(L,a[i])][max(R,a[j])],dp[i+1][j-1][L][R]+(a[j] >= R)+(a[i] <= L));
                      //a[i]与a[j]不交换 
                      dp[i][j][min(L,a[j])][R]=max(dp[i][j][min(L,a[j])][R],dp[i+1][j-1][L][R]+(a[j] <= L));  
                      dp[i][j][L][max(R,a[i])]=max(dp[i][j][L][max(R,a[i])],dp[i+1][j-1][L][R]+(a[i] >= R));
                      dp[i][j][min(L,a[j])][max(R,a[i])]=max(dp[i][j][min(L,a[j])][max(R,a[i])],dp[i+1][j-1][L][R]+(a[i] >= R)+(a[j] <= L));
                       //a[i]与a[j]交换 
                }
          }
      cout<<dp[1][n][1][50]<<endl;
      return 0;
    }
  • 相关阅读:
    Maven安装与配置
    win10更新后程序路径盘符变成*星号解决方法
    谈谈 CSS 关键字 initial、inherit 和 unset
    用 async/await 来处理异步
    Vuex
    HTML5新特性之文件和二进制数据的操作 Blob对象
    vue中class和内联style绑定
    Petya and Staircases CF212div.2B
    CF#212 Two Semiknights Meet
    HDU1423最长上升公共子序列
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9884053.html
Copyright © 2011-2022 走看看