# [DP] BZOJ 4758 [Usaco2017 Jan]Subsequence Reversal

DP 专栏收录该内容
150 篇文章 1 订阅

reverse一个子序列就是从两端开始swap

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=55;
int n,a[N];

int f[N][N][N][N];

inline int dp(int i,int j,int l,int r){
if (f[i][j][l][r]!=-1) return f[i][j][l][r];
if (l>r) return -1<<29;
if (i>j) return 0;
if (i==j) return l<=a[i] && a[i]<=r;

int ret=0;
ret=max(ret,dp(i+1,j,l,r));
ret=max(ret,dp(i,j-1,l,r));

if (a[j]>=l) ret=max(ret,dp(i+1,j-1,a[j],r)+1);
if (a[i]<=r) ret=max(ret,dp(i+1,j-1,l,a[i])+1);
if (l<=a[j] && a[j]<=a[i] && a[i]<=r) ret=max(ret,dp(i+1,j-1,a[j],a[i])+2);

if (a[i]>=l) ret=max(ret,dp(i+1,j,a[i],r)+1);
if (a[j]<=r) ret=max(ret,dp(i,j-1,l,a[j])+1);
if (l<=a[i] && a[i]<=a[j] && a[j]<=r) ret=max(ret,dp(i+1,j-1,a[i],a[j])+2);

return f[i][j][l][r]=ret;
}

int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(f,-1,sizeof(f));
printf("%d\n",dp(1,n,0,50));
return 0;
}

• 0
点赞
• 0
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

06-05 783

08-30 242
10-22 38
09-19 766
06-01 3298
03-24 1530
08-07 347
11-03 1080