不难发现本题贪心是不好做的,可以考虑 \(dp\)。

首先的一个想法就是令 \(dp_{i, j, k, l}\) 表示当前选到第 \(i\) 个位置,当前第一个序列选了 \(j\) 个数,当前第一个序列最后一个元素为 \(k\),第二个序列最后一个元素为 \(l\) 是否合法。这样的话转移十分显然,但复杂度过高了。进一步我们可以发现 \(k, l\) 中一定有一个是 \(a_i\),于是我们可以令 \(dp_{i, j, k, 0 / 1}\) 表示当前选到第 \(i\) 个位置,当前第一个序列选了 \(j\) 个数,选择 \(a_i\) 为结尾的另一个序列的结尾为 \(k\),\(i\) 是第一个序列还是第二个序列选择是否合法。这样的转移也很显然,不再赘述。

下面这个操作就非常骚了,我们可以发现我们 \(dp\) 的值都是 \(0 / 1\),这样感觉非常的亏,我们能不能将状态中的某一维设计到 \(dp\) 值中去呢?答案是可以的,我们令 \(dp_{i, j, 0 / 1}\) 表示当前选到第 \(i\) 个位置,第一个序列选了 \(j\) 个数,\(a_i\) 是第一个还是第二个序列选时另一个序列结尾元素的最小值。那么我们就有转移:

\(dp_{i, j, 0} = \min\{dp_{i, j, 0}, dp_{i - 1, j - 1, 0}\}(a_i > a_{i - 1})\)

\(dp_{i, j, 0} = \min\{dp_{i, j, 0}, a_{i - 1}\}(a_i > dp_{i - 1, j - 1, 1})\)

\(dp_{i, j, 1} = \min\{dp_{i, j, 1}, dp_{i - 1, j, 1}\}(a_i > a_{i - 1})\)

\(dp_{i, j, 1} = \min\{dp_{i, j, 1}, a_{i - 1}\}(a_i > dp_{i - 1, j, 0})\)

最终只需判断 \(dp_{n, \frac{n}{2}, 0 / 1} \ne \infty\) 即可。

#include<bits/stdc++.h>
using namespace std;
#define N 2000 + 5
#define inf 1000000000
#define rep(i, l, r) for(int i = l; i <= r; ++i)
int T, n, a[N], dp[N][N][2];
int read(){
char c; int x = 0, f = 1;
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(){
T = read();
while(T--){
n = read();
rep(i, 1, n) a[i] = read();
rep(i, 1, n) rep(j, 0, min(i, n / 2)) dp[i][j][0] = dp[i][j][1] = inf;
dp[1][1][0] = dp[1][0][1] = -1;
rep(i, 2, n) rep(j, 0, min(i, n / 2)){
if(a[i] > a[i - 1] && j >= 1) dp[i][j][0] = dp[i - 1][j - 1][0];
if(j >= 1 && a[i] > dp[i - 1][j - 1][1]) dp[i][j][0] = min(dp[i][j][0], a[i - 1]);
if(a[i] > a[i - 1]) dp[i][j][1] = dp[i - 1][j][1];
if(a[i] > dp[i - 1][j][0]) dp[i][j][1] = min(dp[i][j][1], a[i - 1]);
}
if(dp[n][n / 2][0] != inf || dp[n][n / 2][1] != inf) puts("Yes!");
else puts("No!");
}
return 0;
}

[HNOI2009]双递增序列的更多相关文章

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

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

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

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

  3. [HNOI2009]双递增序列(动态规划,序列dp)

    感觉这个题还蛮难想的. 首先状态特别难想.设\(dp[i][j]\)表示前i个数,2序列的长度为j的情况下,2序列的最后一个数的最小值. 其中1序列为上一个数所在的序列,2序列为另外一个序列. 这样设 ...

  4. P4728 [HNOI2009]双递增序列

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

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

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

  6. luogu4728 双递增序列 (dp)

    设f[i][j]表示以i位置为第一个序列的结尾,第一个序列的长度为j,第二个序列的结尾的最小值 那么对于f[i][j],有转移$f[i+1][j+1]=min\{f[i+1][j+1],f[i][j] ...

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

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

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

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

  9. ACM: Racing Gems - 最长递增序列

    Racing Gems   You are playing a racing game.  Your character starts at the x axis (y = 0) and procee ...

随机推荐

  1. ZOJ 1141:Closest Common Ancestors(LCA)

    Closest Common Ancestors Time Limit: 10 Seconds      Memory Limit: 32768 KB Write a program that tak ...

  2. Counterfactual VQA: A Cause-Effect Look at Language Bias

    目录 概 主要内容 实现 代码 Niu Y., Tang K., Zhang H., Lu Z., Hua X. and Wen J. Counterfactual VQA: A Cause-Effe ...

  3. 如何优雅地读写HttpServletRequest和HttpServletResponse的请求体

    最近很多交互要同原生的HttpServletRequest和HttpServletResponse打交道.从HttpServletRequest中读取body数据封装成某种数据结构:向HttpServ ...

  4. 如何在HTML中添加表格标题?(HTML中table添加标题的2种方法)

    第一种:通过 fieldset 添加标题框 示例代码: <html> <body> <fieldset> <legend>fieldset添加框标题&l ...

  5. MongoDB常用命令(2)

    1.创建数据库 use testdb 2.创建集合 db.t_member.insert({name:"zhaomin",age:23}) 3.查询 db.t_member.fin ...

  6. python+pytest,通过自定义命令行参数,实现浏览器兼容性跑用例

    场景拓展: UI自动化可能需要指定浏览器进行测试,为了做成自定义配置浏览器,可以通过动态添加pytest的命令行参数,在执行的时候,获取命令行传入的参数,在对应的浏览器执行用例. 1.自动化用例需要支 ...

  7. django中写入数据时给密码加密

    方法一.在自定义的form表单中重写save方法: 方法二.使用信号量来实现 1. 在应用的模块下新建signal.py文件 2.编写回调函数,内容如下: 3. 在应用的app.py文件中的ready ...

  8. 详谈 Java工厂 --- 抽象工厂模式

    1.前言 感觉工厂模式都好鸡肋,还特别绕来绕去,当然,好处还是有的,将一些类似的业务都集成到工厂了, 不需要理会底层是怎么运行的,我只需要向调用工厂即可获取我要的结果,也不需要考虑工厂返回的东西类型, ...

  9. js获取相邻节点的value值

    document.getElementById('id').nextElementSibling.value或者document.getElementById('id').previousElemen ...

  10. html手机调试

    长话短说 npm install anywhere -g 安装好后,cmd 命令 进入你要调试html页面的目录,运行 anywhere AnyWhere 静态文件服务器 软件简介 AnyWhere是 ...