感觉这个题还蛮难想的.

首先状态特别难想.设\(dp[i][j]\)表示前i个数,2序列的长度为j的情况下,2序列的最后一个数的最小值.

其中1序列为上一个数所在的序列,2序列为另外一个序列.

这样设状态的巧妙之处在于,它几乎完美地用最精炼的语言描述了序列的信息,使我们可以方便地转移.我们现在知道1序列的最后一个数\(seq[i]\),2序列的最后一个数\(dp[i][j]\).1序列的长度\(i-j\),2序列的长度\(j\).

于是转移就是:

如果可以接在1序列上的话,即\(seq[i-1]<seq[i]\),那么\(dp[i][j]=min(dp[i][j],dp[i-1][j])\)

如果可以接在2序列上的话,即\(dp[i-1][i-j]<seq[i]\)(可以接在2序列上,但是由于状态是2序列的长度,所以两个序列要交换,所以是i-j),那么1序列和2序列要互换,此时2序列的最后一个元素就是之前1序列的最后一个元素\(seq[i-1]\),即\(dp[i][k]=min(dp[i][j],seq[i-1])\)

#include<bits/stdc++.h>
#define maxn 2005
using namespace std;
int seq[maxn],n;
int dp[maxn][maxn];
//dp[i][j]表示前i个数,2序列长度为j,2序列最后一个数的最小值.
int main()
{
int T;cin>>T;
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&seq[i]);
memset(dp,0x3f,sizeof(dp));dp[0][0]=-1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=min(n/2,i);j++)
{
if(seq[i-1]<seq[i])dp[i][j]=dp[i-1][j];
//大于前一个数,说明可以直接接在前一个数之后,2序列的最后元素不需要变大
if(dp[i-1][i-j]<seq[i])dp[i][j]=min(dp[i][j],seq[i-1]);
//大于2序列的最后一个数,说明可以接在2序列之后,此时1序列和2序列交换
//本来作为数组里的值表示的现在变成下标体现,原本下标体现的现在变成值
//1序列表示上一次的数所在的序列,2序列是另一个序列
//seq[i-1]是1序列最后一个元素
}
}
if(dp[n][n/2]<=1e6)printf("Yes!\n");
else printf("No!\n");
}
return 0;
}

[HNOI2009]双递增序列(动态规划,序列dp)的更多相关文章

  1. 【BZOJ1489】[HNOI2009]双递增序列(动态规划)

    [BZOJ1489][HNOI2009]双递增序列(动态规划) 题面 BZOJ 洛谷 题解 这\(dp\)奇奇怪怪的,设\(f[i][j]\)表示前\(i\)个数中,第一个数列选了\(j\)个数,第二 ...

  2. [luogu4728 HNOI2009] 双递增序列 (dp)

    传送门 Solution 前几天刚做了类似题,这种将一个序列拆分为两个单调序列的题一般都是设\(dp[i]\)表示i为一个单调序列的末尾时,另一个序列的末尾是多少 然后应用贪心的思想,在这道题中就是让 ...

  3. [HNOI2009]双递增序列(洛谷P4728)+小烈送菜(内部训练题)——奇妙的dp

    博主学习本题的经过嘤嘤嘤: 7.22 : 听学长讲(一知半解)--自己推(推不出来)--网上看题解--以为自己会了(网上题解是错的)--发现错误以后又自己推(没推出来)--给学长发邮件--得到正确解法 ...

  4. P4728 [HNOI2009]双递增序列

    题意 这个DP状态有点神. 首先考虑一个最暴力的状态:\(f_{i,j,k,u}\)表示第一个选了\(i\)个,第二个选了\(j\)个,第一个结尾为\(k\),第二个结尾为\(u\)是否可行. 现在考 ...

  5. [HNOI2009]双递增序列

    不难发现本题贪心是不好做的,可以考虑 \(dp\). 首先的一个想法就是令 \(dp_{i, j, k, l}\) 表示当前选到第 \(i\) 个位置,当前第一个序列选了 \(j\) 个数,当前第一个 ...

  6. BZOJ 1489: [HNOI2009]双递增序( dp )

    dp(i, j)表示选第i个, 且当前序列长度为j, 另一个序列的最后一个元素的最小值...然后根据上一个是哪个序列选的讨论一下就行了...奇怪的dp... --------------------- ...

  7. [BZOJ 1489][HNOI2009]双递增序

    传送门 满满的负罪感,昨晚的刷题历程:写几道难题吧-->算了,还是只切道水题吧-->RNG赢了...... 背包一下就行了 #include <bits/stdc++.h> u ...

  8. nyoj 17-单调递增最长子序列 && poj 2533(动态规划,演算法)

    17-单调递增最长子序列 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:21 submit:49 题目描述: 求一个字符串的最长递增子序列的长度 如 ...

  9. nyoj17-单调递增最长子序列-(dp)

    17-单调递增最长子序列 内存限制:64MB 时间限制:3000ms 特判: No通过数:125 提交数:259 难度:4 题目描述: 求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列 ...

随机推荐

  1. [记录]一则HTTP配置文件参考记录

    # cat ../conf/httpd.conf | grep -vE "^$|^#" ServerTokens OS ServerRoot "/etc/httpd&qu ...

  2. 查看http请求的header信息

    1 下载chrome浏览器 chrome浏览器是google开发的一块非常绑定浏览器.chrome浏览器下载地址. 2 通过chrome控制台查看http请求的header信息 2.1 打开chrom ...

  3. 【Go】类似csv的数据日志组件设计

    原文链接:https://blog.thinkeridea.com/201907/go/csv_like_data_logs.html 我们业务每天需要记录大量的日志数据,且这些数据十分重要,它们是公 ...

  4. Java多线程下载器FileDownloader(支持断点续传、代理等功能)

    前言 在我的任务清单中,很早就有了一个文件下载器,但一直忙着没空去写.最近刚好放假,便抽了些时间完成了下文中的这个下载器. 介绍 同样的,还是先上效果图吧. Jar包地址位于 FileDownload ...

  5. python 面向对象编程 - 小游戏

    面向对象写的小游戏 欢迎玩耍 class Omnicience: camp = 'Omniscience' def __init__(self, name, atk=100, hp=1000, mp= ...

  6. TensorFlow笔记-文件读取

    小数量数据读取 这些只用于可以完全加载到内存中的小型数据集: 1,储存在常数中 2,储存在变量中,初始化后,永远不改变它的值 使用常量 training_data = ... training_lab ...

  7. 小白开学Asp.Net Core《二》(补)

    小白开学Asp.Net Core<二>(补) ——数据仓储层(Repositroy).服务层(Service) -------------------------------------- ...

  8. Flask项目常见面试问题

    一.你的项目中缓存粒度是如何选择的? 缓存粒度一共分为4种. 1.缓存某个数值:一个键只保存一个值,性价比较低,使用率低,如果存储的话我们使用redis的String 2.缓存数据对象:数据库记录对应 ...

  9. Hadoop学习(3)-mapreduce快速入门加yarn的安装

    mapreduce是一个运算框架,让多台机器进行并行进行运算, 他把所有的计算都分为两个阶段,一个是map阶段,一个是reduce阶段 map阶段:读取hdfs中的文件,分给多个机器上的maptask ...

  10. jmter快速安装

    一.简介 Apache JMeter是Apache组织开发的基于Java的压力测试工具,用于接口和压力测试,所以前提是一定更要安装jdk. 二.下载安装 下载:官网下载 下载完成后运行包里的jmete ...