题目描述

Farmer John is arranging his NN cows in a line to take a photo (1 \leq N \leq 501≤N≤50). The height of the iith cow in sequence is a(i)a(i), and Farmer John thinks it would make for an aesthetically pleasing photo if the cow lineup has a large increasing subsequence of cows by height.

FJ would like there to be a long increasing subsequence within his ordering of the cows. In order to ensure this, he allows himself 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 subsequence, given that you can choose to reverse an arbitrary subsequence once.

FJ正在安排他的N头奶牛排成一队以拍照(1<=n<=50)。队列中的第i头奶牛的身高为a[i],并且FJ认为如果奶牛的身高序列中含有一个很长的不下降子序列的话,这会是一张很好的照片。

回忆一下,子序列是由牛序列中的一些元素a[i_1],a[i_2],.....a[i_k]组成的子集。(i_1<i_2<...<i_k) 如果a[i_1]<=a[i_2]<=a[i_3]<=......<=a[i_k]的话,我们就说这个序列是不下降的。

FJ想要在他的奶牛序列中包括一个长期增长的子序列(也就是很长的不下降子序列)。为了确保这一点,他允许自己在一开始选择任何子序列并逆转其元素。

观察这个子序列(上方英文)是如何反转并占据他们最初的相同的位置的,且其他元素保持不变。

在只能反转一次任意子序列的情况下,请找到不下降子序列的最大可能长度。

输入输出格式

输入格式:

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

第一行一个整数N。

接下来N行包括N个整数a[1]...a[n],每行一个在1到50之间的整数。

输出格式:

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

输出反转一次任意子序列后所得到的不下降子序列的最大可能长度。

输入输出样例

输入样例#1:

9

1

2

3

9

5

6

8

7

4

输出样例#1:

9

解题报告:

很巧妙的思维题啊,一开始丝毫没有思路,瞟了一眼题解,看到一句话:交换一个序列相当于不相交的交换几个元素.因为这几个元素交换之后就相当于是交换了一个子序列

有了这句话的提示,问题就迎刃而解了.关键要做到交换的元素不能相交,其实只需要DP的顺序没问题即可,那么显然假设[L,R]已经解决了,那么交换的元素就强制只能在[L,R]之外.

下面正式开始DP,定义\(f[l][r][i][j]\)表示区间[l,r]间,值域在[i,j]间的最长上升子序列的长度,那么就转移就是交换和不交换的区别.

\(f[l][r][i][j]=Max(f[l+1][r][i][j]+(a[l]==i),f[l][r-1][i][j]+(a[r]==j))\)

\(f[l][r][i][j]=Max(f[l+1][r-1][i][j]+(a[l]==j)+(a[r]==i))\)

一式是不交换的转移,二式是交换的转移

注意:\(f[l][r][i-1][j]=f[l][r][i][j]\),\(f[l][r][i][j+1]=f[l][r][i][j]\)

注意值域是可以向两边扩展的

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=55;
int n,a[N],f[N][N][N][N];
void work()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=a[i];j++)
for(int k=a[i];k<=50;k++)
f[i][i][j][k]=1;
}
for(int k=2;k<=n;k++){
for(int l=1;l<=n;l++){
int r=l+k-1;if(r>n)break;
for(int i=1;i<=50;i++){
for(int j=i;j<=50;j++){
f[l][r][i][j]=Max(f[l][r][i][j],
Max(f[l+1][r][i][j]+(a[l]==i),
f[l][r-1][i][j]+(a[r]==j)));
f[l][r][i][j]=Max(f[l][r][i][j],
f[l+1][r-1][i][j]+
(a[r]==i)+(a[l]==j));
f[l][r][i][j+1]=
Max(f[l][r][i][j+1],f[l][r][i][j]);
f[l][r][i-1][j]=
Max(f[l][r][i-1][j],f[l][r][i][j]);
}
}
for(int j=1;j<=50;j++)
for(int i=j;i>=1;i--)
f[l][r][i-1][j]=Max(f[l][r][i-1][j],f[l][r][i][j]);
}
}
printf("%d\n",f[1][n][1][50]);
} int main()
{
work();
return 0;
}

[USACO17JAN]Subsequence Reversal序列反转的更多相关文章

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

    题目大意:给你一个序列,你可以翻转任意一段子序列一次,求最长不下降子序列长度 tips:子序列可以不连续,但不能破坏在原序列中的顺序 观察数据范围,n<=50,很小,考虑dfs *dfs来跑区间 ...

  2. [USACO17JAN]Subsequence Reversal

    嘟嘟嘟 这题刚开始是什么思路也没有,关键是不知道怎么解决序列反转的问题. 然后我就想到如果暴力反转一个序列的话,实际上就是不断交换数组中的两个数ai和aj,同时要满足交换的数不能交叉. 然后又看了一眼 ...

  3. bzoj4758: [Usaco2017 Jan]Subsequence Reversal(区间dp)

    4758: [Usaco2017 Jan]Subsequence Reversal Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 76  Solved ...

  4. Python-序列反转和序列反转协议-reversed __reversed__

    reversed 将序列反转,依次把最后的元素放到第一个位置,把第一元素放到最后一个位置,变成生成器对象 name = "beimenchuixue" print(next(rev ...

  5. 2018.08.16 洛谷P3607 [USACO17JAN]序列反转(线性dp)

    传送门 一道感觉比较简单的dp. 注意是要求翻转一个子序列而不是一段连续的数(被坑了很多次啊)... 看到数据范围果断开一个四维数组来dp一波. 我们显然可以用f[i][j][k][t]表示下标在[l ...

  6. Common Subsequence 最大公共子序列问题

    Problem Description A subsequence of a given sequence is the given sequence with some elements (poss ...

  7. Subsequence(序列自动机模板题)

    题目链接:https://nanti.jisuanke.com/t/38232 题目大意:给你一个字符串,然后再给你m个字符串,然后问你在第一个字符串中不连续的子串能不能构成输入的子串. 具体思路:构 ...

  8. 376 Wiggle Subsequence 摆动序列

    A sequence of numbers is called a wiggle sequence if the differences between successive numbers stri ...

  9. 学习笔记TF020:序列标注、手写小写字母OCR数据集、双向RNN

    序列标注(sequence labelling),输入序列每一帧预测一个类别.OCR(Optical Character Recognition 光学字符识别). MIT口语系统研究组Rob Kass ...

随机推荐

  1. Beta冲刺Day4

    项目进展 李明皇 今天解决的进度 因服务器端未完成登录态维护,故无法进行前后端联动. 明天安排 前后端联动调试 林翔 今天解决的进度 因上课和实验室事务未完成登录态维护 明天安排 完成登录态维护 孙敏 ...

  2. 洛谷 P3797 妖梦斩木棒

    https://www.luogu.org/problem/show?pid=3797 题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了 ...

  3. submit()提交表单时,显示警示框

    我同事在实现submit()提交表单时,想要页面弹出警示框. 但是折腾了几小时后发现,submit()始终不执行. 她的代码如下: $(document).ready(function(){ $(&q ...

  4. 【bug清除】Surface Pro系列使用Drawboard PDF出现手写偏移、卡顿、延迟现象的解决方式

    最近自己新买的New Surface Pro在使用Drawboard PDF时,出现了性能问题,即笔迹延迟偏移,卡顿的问题. 排查驱动问题之后,确认解决方案如下: 将Surface的电池调到性能模式, ...

  5. Python脚本自动提取和替换代码中的中文

    # -*- coding: utf-8 -*- import os import os.path import re import sys reload(sys) sys.setdefaultenco ...

  6. JAVA_SE基础——55.自定义异常类

    在Java中已经提供了大量的异常类,但是这些异常类有时野很难满足开发者的要求,所以用户可以根据自己的需要来定义自己的异常类.但自定义的异常类必须继承自Exception或其子类. 可以自定义出的问题称 ...

  7. kubernetes进阶(04)kubernetes的service

    一.service概念 Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口.借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级.Service ...

  8. kubernetes入门(08)kubernetes单机版的安装和使用

    kubectl get - 类似于 docker ps ,查询资源列表 kubectl describe - 类似于 docker inspect ,获取资源的详细信息 kubectl logs - ...

  9. 发布到NPMJS

    最近在做微服务的前后端设计,打算将客户端中的一个模块独立出来发布到npmjs上,因此,有机会了解了一下npm的发布过程. 参考了很多网上的文章,长篇累牍(但在这里还是真心感谢他们的分享),最终总结成一 ...

  10. Python之递归函数

    递归函数 初识递归函数 递归函数的定义:在一个函数里再调用这个函数本身 Python为了考虑保护内存占用情况,有一个递归深度的限制. 探究递归的默认最大深度: def foo(n): print(n) ...