• [USACO17JAN] Subsequence Reversal序列反转 (dfs+记忆化)


    题目大意:给你一个序列,你可以翻转任意一段子序列一次,求最长不下降子序列长度 

    tips:子序列可以不连续,但不能破坏在原序列中的顺序

    观察数据范围,n<=50,很小,考虑dfs

    *dfs来跑区间dp可以巧妙的解决区间两端元素的置换问题

     记忆化搜索,f[i][j][l][r] 代表对于区间[i,j],构成最长不下降子序列的元素值域在[l,r]时,最长不下降子序列的长度

    注意特判端点

     1 #include <bits/stdc++.h>
     2 #define N 55
     3 #define inf 0x3f3f3f3f
     4 using namespace std;
     5  
     6 int n,m;
     7 int a[N],f[N][N][N][N];
     8 int dfs(int i,int j,int l,int r)
     9 {
    10     int ans=-1;
    11     if(f[i][j][l][r]!=-1) {return f[i][j][l][r];}
    12     if(l>r) {return -1;}
    13     if(i>j) {return 0;}
    14     if(i==j&&l<=a[i]&&a[i]<=r) {f[i][j][l][r]=1;return 1;}
    15     if(i==j&&(a[i]<l||a[i]>r)) {f[i][j][l][r]=0;return 0;}
    16     ans=max(ans,dfs(i+1,j,l,r));
    17     ans=max(ans,dfs(i,j-1,l,r));
    18     ans=max(ans,dfs(i+1,j-1,l,r));
    19     if(l<=a[i]&&a[i]<=r) {ans=max(ans,dfs(i+1,j,a[i],r)+1);}
    20     if(l<=a[j]&&a[j]<=r) {ans=max(ans,dfs(i,j-1,l,a[j])+1);}
    21     if(l<=a[i]&&a[i]<=a[j]&&a[j]<=r) {ans=max(ans,dfs(i+1,j-1,a[i],a[j])+2);}
    22     
    23     if(l<=a[j]) {ans=max(ans,dfs(i+1,j-1,a[j],r)+1);}
    24     if(a[i]<=r) {ans=max(ans,dfs(i+1,j-1,l,a[i])+1);}
    25     if(r>=a[i]&&a[i]>=a[j]&&a[j]>=l) {ans=max(ans,dfs(i+1,j-1,a[j],a[i])+2);}
    26     f[i][j][l][r]=max(0,ans);
    27     return ans;
    28 }
    29  
    30 int main()
    31 {
    32     scanf("%d",&n);
    33     for(int i=1;i<=n;i++) 
    34         {scanf("%d",&a[i]);}
    35     memset(f,-1,sizeof(f));
    36     printf("%d",dfs(1,n,1,50));
    37     return 0;
    38 }
  • 相关阅读:
    egret 里面设置MovieClip的scale缩放值时,没有效果的情况
    游戏中的胜场数,净胜场数的计算
    使用Laya引擎和AS3(非原生AS)开发手游相关 总结常见bug
    javascript 一些注意事项
    JavaScript面向对象学习小结
    编写协议时注意事项
    Jenkins 在windows系统上的安装与使用
    LayaAir2.0 自定义Mesh-画圆环
    LayaAir2.0 自定义Mesh-画扇形
    Cocos Creator 使用 protobuf
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9696843.html
Copyright © 2020-2023  润新知