【BZOJ1049】【Luogu P2501】 [HAOI2006]数字序列 DP,结论,LIS
很有(\(bu\))质(\(hui\))量(\(xie\))的一个题目。
第一问:求最少改变几个数能把一个随机序列变成单调上升序列。
\(Solution:\)似乎是一个结论?如果两个数\(A_i\)和\(A_j\)可以保留(\(i > j, A_i > A_j\)),即中间其他数都可以通过修改成为\([A_i, A_j]\)区间内的一个数,那么一定有\(i - j <= A_i - A_j\),即\(A_i - i >= A_j - j\)。这个东西我们可以设为数列\(B\),求一个最长不下降子序列就可以了。
(其实我中间智障了写成了最长上升子序列居然还有\(90ptshhhhh\))
第二问:结论看这里。有了第一问的铺垫其实并不难想,但是问题在于可以有很多种最长不下降子序列,该怎么办?
我们考虑对答案\(DP\),设\(f_x\)为前\(x\)个数有序化的最小代价(其中\(x\)一定是一个子序列内的点),然后来一发轻松愉快的\(DP\)。由于数据完全随机,所以可以剪枝过去。(虽然就是不随机恐怕也很难卡满就是了\(QwQ\))
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 35000 + 5;
const int INF = 0x3f3f3f3f;
int n, A[N], B[N], Longest[N];
vector <int> q, G[N];
vector <int> :: iterator it;
int solve1 () {
for (int i = 1; i <= n + 1; ++i) {
if (q.empty () || B[i] >= q[q.size () - 1]) {
q.push_back (B[i]); Longest[i] = q.size ();
} else {
it = upper_bound (q.begin (), q.end (), B[i]);
*it = B[i]; Longest[i] = it - q.begin () + 1;
}
G[Longest[i]].push_back (i);
}
// Longest[i] : 以 i 结尾的最长不下降子序列
return q.size () - 1; // 可以保留的数的个数
}
int dp[N], hl[N], hr[N]; // hl[i] -> 从 l 到 i 都选择变成左端点值的代价, hr 同理
int solve2 () {
memset (dp, 0x3f, sizeof (dp));
dp[0] = 0; G[0].push_back (0);
for (int v = 1; v <= n + 1; ++v) {
for (int i = 0; i < G[Longest[v] - 1].size (); ++i) {
int u = G[Longest[v] - 1][i];
// cout << "u = " << u << " v = " << v << endl;
if (v < u || B[v] < B[u]) continue;
hl[u] = hr[v] = 0;
for (int k = u + 1; k < v; ++k) {
hl[k] = hl[k - 1] + abs (B[k] - B[u]);
}
for (int k = v - 1; k > u; --k) {
hr[k] = hr[k + 1] + abs (B[k] - B[v]);
}
for (int k = u; k < v; ++k) {
dp[v] = min (dp[v], dp[u] + hl[k] + hr[k + 1]);
}
}
}
return dp[n + 1];
}
signed main () {
// freopen ("data.in", "r", stdin);
// freopen ("data.out", "w", stdout);
cin >> n;
B[0] = -INF, B[n + 1] = INF;
for (int i = 1; i <= n; ++i) {
cin >> A[i]; B[i] = A[i] - i;
}
cout << n - solve1 () << endl; // 对数列 B 做最长不下降子序列
cout << solve2 () << endl; // ans
}
【BZOJ1049】【Luogu P2501】 [HAOI2006]数字序列 DP,结论,LIS的更多相关文章
- 2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS)
2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS) https://www.luogu.com.cn/problem/P2501 题意: 现在我们有一个长度为 n 的整 ...
- Luogu P2501 [HAOI2006]数字序列
题目 首先把\(a\)改成严格单调上升等于把\(a_i-i\)改成单调不降. 那么第一问可以直接做LIS,答案就是\(n-\)LIS的长度. 同时我们记录一下序列中每个位置结尾的LIS长度. 第二问我 ...
- 洛谷 P2501 [HAOI2006]数字序列 解题报告
P2501 [HAOI2006]数字序列 题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. ...
- BZOJ1049:[HAOI2006]数字序列(DP)
Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列. 但是不希望改变过多的数,也不希望改变的幅度太大. Input 第一行包含一个 ...
- P2501 [HAOI2006]数字序列 (LIS,DP)(未完成)
第二问好迷... #include "Head.cpp" #include <vector> const int N = 35007; vector<int> ...
- p2501 [HAOI2006]数字序列
传送门 分析 https://www.luogu.org/blog/FlierKing/solution-p2501 对于第二问的感性理解就是有上下两条线,一些点在上面的线的上面或者下面的线的下面,然 ...
- [luogu2501 HAOI2006] 数字序列 (递推LIS)
题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. 输入输出格式 输入格式: 第一行包含一个数 ...
- 【BZOJ1049】 [HAOI2006]数字序列
BZOJ1049 [HAOI2006]数字序列 dp好题? 第一问 第一问我会做!令\(b_i=a_i-i\),求一个最长不下降子序列. \(n-ans\)就是最终的答案. 第二问 好难啊.不会.挖坑 ...
- bzoj 1049 [HAOI2006]数字序列
[bzoj1049][HAOI2006]数字序列 Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不 ...
随机推荐
- flask 之(四) --- 扩展|缓存|会话
扩展 蓝图内置扩展 (实现的是路由的拆分) '''----------- app.py -------------''' from flask import Flask from users_view ...
- 5分钟了解图数据库Neo4j的使用
1.图数据库安装与配置 1.1安装与配置 配置path = %NEO4J_HOME%\bin 启动命令:neo4j console web访问:http://localhost:7474 1. ...
- sql注入知识点整理(基础版)
sql注入知识点整理(基础版) 基本步骤 判断是否报错 判断闭合符号 判断注入类型 构建payload 手工注入或者编写脚本 基本注入类型 报错型注入 floor公式(结果多出一个1):and (se ...
- 我和CMS的往事
CMS(内容管理系统)放在web中理解,也就是我们常说的后台了,用于网站的日常管理.又到期末了,我们的课程——web程序设计,需要提交一份期末大作业,最近需要开发出一个基于JSP的简单web,所以呢, ...
- nginx反向代理集群配置
#user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...
- 【坑】不要使用各种框架提供的内部List
为了代码简洁有时我们会使用一些框架提供的工具类.如 import org.apache.commons.collections.ListUtils; package java.util.Collect ...
- [转帖](整理)GNU Hurd项目详解
(整理)GNU Hurd项目详解 http://www.ha97.com/3188.html 发表于: 开源世界 | 作者: 博客教主 标签: GNU,Hurd,详解,项目 Hurd原本是要成为GNU ...
- 如何解决Oracle11g使用dmp命令无法导出空表问题
如何解决Oracle11g使用dmp命令无法导出空表问题 导出:exp username/password@orcl file=路径 tables=(tb1) //tables=(tb1)可有 ...
- JS中this的4种绑定规则
this ES6中的箭头函数采用的是词法作用域. 为什么要使用this:使API设计得更简洁且易于复用. this即不指向自身,也不指向函数的词法作用域. this的指向只取决于函数的调用方式 thi ...
- Java小程序—录屏小程序(下半场)
下半场. 上半场,我们我们写了录屏的程序,那么下半场我们的任务是写一个播放器. 设计思路:播放器的思路就是将图片放在一个JScrollPane中顺序播放,所以还是得使用swing组件,并且仍然要使用线 ...