P4728 [HNOI2009]双递增序列
题意
这个DP状态有点神。
首先考虑一个最暴力的状态:\(f_{i,j,k,u}\)表示第一个选了\(i\)个,第二个选了\(j\)个,第一个结尾为\(k\),第二个结尾为\(u\)是否可行。
现在考虑消减状态:
1.首先知道了处理到第几个,那么只要知道一个长度就能推出另一个。 因此状态可以改为\(f_{i,j,k,u}\)表示处理到了第\(i\)个,第一个序列选了\(j\)个,第一个序列结尾为\(k\),第二个序列结尾为\(u\)是否可行。(这并没有减少维数,只是转化下,方便处理。)
2.既然所有的数都要选,假设当前处理到了第\(i\)个,那么第\(i-1\)个必定在结尾,因此我们可以消去一维:
\(f_{i,j,k}\)表示处理到第\(i\)个,结尾是\(a_i\)的那个序列长度为\(j\),另一个结尾为\(k\)是否可行。
3.贪心地想,一个序列结尾越小越容易接数,因此可以将一维放到DP的值中:
\(f_{i,j}\)表示处理到第\(i\)个,结尾是\(a_{i-1}\)的那个序列长度为\(j\),另一个结尾最小是多少。
现在我们已经将DP减到二维,于是就可以转移了:
\(a_i>a_{i-1}\):此时\(a_i\)可以拼接在\(a_{i-1}\)后面:
\(f_{i,j}=\min(f_{i,j}f_{i-1,j-1})\)。
\(a_i>f_{i-1,i-j}\):此时我们可以将\(a_i\)接到另一个序列后面,于是我们交换两个序列,因为另一个序列后面接了\(a_i\),我们要符合定义,于是可得:
\(f_{i,j}=\min(f_{i,j},a_{i-1})\)。
最后判断\(f_{n,n/2}\)是否为\(inf\)。
数据范围不知道,到某dark上看了看,\(n\leqslant2000\)。
code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2010;
int T,n;
int a[maxn];
int f[maxn][maxn];
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
memset(f,0x3f,sizeof(f));
f[0][0]=-1;
for(int i=1;i<=n;i++)
for(int j=1;j<=min(n/2,i);j++)
{
if(a[i]>a[i-1])f[i][j]=min(f[i][j],f[i-1][j-1]);
if(a[i]>f[i-1][i-j])f[i][j]=min(f[i][j],a[i-1]);
}
puts(f[n][n/2]<0x3f3f3f3f?"Yes!":"No!");
}
return 0;
}
P4728 [HNOI2009]双递增序列的更多相关文章
- 【BZOJ1489】[HNOI2009]双递增序列(动态规划)
[BZOJ1489][HNOI2009]双递增序列(动态规划) 题面 BZOJ 洛谷 题解 这\(dp\)奇奇怪怪的,设\(f[i][j]\)表示前\(i\)个数中,第一个数列选了\(j\)个数,第二 ...
- [HNOI2009]双递增序列(洛谷P4728)+小烈送菜(内部训练题)——奇妙的dp
博主学习本题的经过嘤嘤嘤: 7.22 : 听学长讲(一知半解)--自己推(推不出来)--网上看题解--以为自己会了(网上题解是错的)--发现错误以后又自己推(没推出来)--给学长发邮件--得到正确解法 ...
- [luogu4728 HNOI2009] 双递增序列 (dp)
传送门 Solution 前几天刚做了类似题,这种将一个序列拆分为两个单调序列的题一般都是设\(dp[i]\)表示i为一个单调序列的末尾时,另一个序列的末尾是多少 然后应用贪心的思想,在这道题中就是让 ...
- [HNOI2009]双递增序列(动态规划,序列dp)
感觉这个题还蛮难想的. 首先状态特别难想.设\(dp[i][j]\)表示前i个数,2序列的长度为j的情况下,2序列的最后一个数的最小值. 其中1序列为上一个数所在的序列,2序列为另外一个序列. 这样设 ...
- [HNOI2009]双递增序列
不难发现本题贪心是不好做的,可以考虑 \(dp\). 首先的一个想法就是令 \(dp_{i, j, k, l}\) 表示当前选到第 \(i\) 个位置,当前第一个序列选了 \(j\) 个数,当前第一个 ...
- luogu4728 双递增序列 (dp)
设f[i][j]表示以i位置为第一个序列的结尾,第一个序列的长度为j,第二个序列的结尾的最小值 那么对于f[i][j],有转移$f[i+1][j+1]=min\{f[i+1][j+1],f[i][j] ...
- BZOJ 1489: [HNOI2009]双递增序( dp )
dp(i, j)表示选第i个, 且当前序列长度为j, 另一个序列的最后一个元素的最小值...然后根据上一个是哪个序列选的讨论一下就行了...奇怪的dp... --------------------- ...
- [BZOJ 1489][HNOI2009]双递增序
传送门 满满的负罪感,昨晚的刷题历程:写几道难题吧-->算了,还是只切道水题吧-->RNG赢了...... 背包一下就行了 #include <bits/stdc++.h> u ...
- ACM: Racing Gems - 最长递增序列
Racing Gems You are playing a racing game. Your character starts at the x axis (y = 0) and procee ...
随机推荐
- Git实战指南----跟着haibiscuit学Git(第十一篇)
笔名: haibiscuit 博客园: https://www.cnblogs.com/haibiscuit/ Git地址: https://github.com/haibiscuit?tab=re ...
- idea git提交代码步骤
这位兄台已经写的很清楚了... 我这里直接给你们链接把... https://blog.csdn.net/u013452337/article/details/79956604 Git 初次提交,以及 ...
- Python—定时任务(APScheduler实现)
简介 APScheduler的全称是Advanced Python Scheduler.它是一个轻量级的基于Quartz的 Python 定时任务调度框架.APSche ...
- ADB常用命令(一)
转自:https://blog.csdn.net/qq_26552691/article/details/81348222 一.操作前请确认电脑上已配置好ADB环境.可在CMD命令行输入adb,如果出 ...
- 浅谈C++ STL string容器
浅谈C++ STL string容器 本篇随笔简单讲解一下\(C++STL\)中\(string\)容器的使用方法及技巧. string容器的概念 其实\(string\)并不是\(STL\)的一种容 ...
- Jenkins学习安装配置和使用
为了能够频繁地将软件的最新版本,及时.持续地交付给测试团队及质量控制团队,以供评审,所以引入持续集成工具Jenkins,从而实现公司新产品持续集成,自动化部署. 环境准备 ●操作系统:Windows1 ...
- PHP收集一些常用函数与好用的自定义函数
.自定义打印函数P //自定义打印function pp($data,$exit=0){// 定义样式 $str='<pre style="display: block;padding ...
- 【分析工具】阿里巴巴Arthas--线上问题分析利器
目录 1. Arthas是什么 2. Arthas能解决什么问题 3. 快速安装 第一步:下载 第二步:运行 第三步:选择进程 4. 实战使用 5. 总结 本博客转载自阿里开源的 Java 诊断工具 ...
- 某小公司RESTful、共用接口、前后端分离、接口约定的实践
作者:邵磊 juejin.im/post/59eafab36fb9a045076eccc3 前言 随着互联网高速发展,公司对项目开发周期不断缩短,我们面对各种需求,使用原有对接方式,各端已经很难快速应 ...
- SpringMVC参数绑定,这篇就够了!
SpringMVC参数绑定,简单来说就是将客户端请求的key/value数据绑定到controller方法的形参上,然后就可以在controller中使用该参数了 下面通过5个常用的注解演示下如何进行 ...