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;
    }
  • 相关阅读:
    ulimit -a
    nginx check_http_send type=http 查检测不到后端TOM的存活
    通过ip查找能应机器的MAC
    错误状态码URL重定向
    error_page 改变状态码为新的状态码,并显示指定内容
    使用 CefSharp 在 C# App 中嵌入 Chrome 浏览器
    C#客户端嵌入Chrome浏览器的实现
    Task.Run c#启动线程
    C#利用webBrowser怎么去掉网页中不想显示的部分
    InDesign CC 2019安装包+破解
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9884053.html
Copyright © 2011-2022 走看看