SCUT - 365 - 鹏哥的数字集合 - wqs二分 - 斜率优化dp
https://www.luogu.org/problemnew/solution/P2365
写这篇的时候还不是很明白,看一下这个东西。
https://www.cnblogs.com/CreeperLKF/p/9045491.html
还是不懂,去问学长了,叫做wqs二分。要求恰好选m个的这种题,每个物品放一个附加权值C。
https://blog.csdn.net/chenxiaoran666/article/details/83381779
既然原来选得越多越优,那么我们可以给选择一个物品增加一个代价C(C可以拿来二分),由于总贡献增长得越来越慢,所以最后肯定会形成一个单峰函数,然后我们就可以通过DP等方式 来求解出此时的最优答案以及最优答案选择的物品个数,并根据选择的物品个数来更新C的值。
是通过给分段附加一个比较大的权值,使得分段越多的不一定更优了,从而控制凸壳上的点的数量,但是这个控制的时候为什么是单调的呢?
胡大佬的标程
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300010;
ll dp[MAXN], a[MAXN], n, m, cnt[MAXN], que[MAXN];
ll X(int i, int j) {
return a[j + 1] - a[i + 1];
}
ll Y(int i, int j) {
return (dp[j] + a[j + 1] * a[j + 1]) - (dp[i] + a[i + 1] * a[i + 1]);
}
ll DP(int i, int j) {
return dp[j] + (a[i] - a[j + 1]) * (a[i] - a[j + 1]);
}
ll solve(ll C) {
dp[0] = 0;
cnt[0] = 0;
int s = 0, t = 0;
que[++t] = 0;
for(int i = 1; i <= n; i++) {
while(s + 1 < t && Y(que[s + 1], que[s + 2]) < 2LL * a[i] * X(que[s + 1], que[s + 2]))
s++;
dp[i] = DP(i, que[s + 1]) + C;
cnt[i] = cnt[que[s + 1]] + 1;
while(s + 1 < t && 1LL * Y(que[t], i) * X(que[t - 1], que[t]) <= 1LL * Y(que[t - 1], que[t]) * X(que[t], i))
t--;
que[++t] = i;
}
return cnt[n];
}
int main() {
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
sort(a + 1, a + 1 + n);
ll l = 0, r = 1e12;
while(l < r) {
int mid = (l + r) >> 1;
int tmp = solve(mid);
if(tmp <= m)
r = mid;
else
l = mid + 1;
}
solve(r);
printf("%lld\n", dp[n] - m * r);
}
SCUT - 365 - 鹏哥的数字集合 - wqs二分 - 斜率优化dp的更多相关文章
- Gym - 101981B Tournament (WQS二分+单调性优化dp)
题意:x轴上有n个人,让你放置m个集合点,使得每个人往离他最近的集合点走,所有人走的距离和最短. 把距离视为花费,设$dp[i][k]$表示前i个人分成k段的最小花费,则有递推式$dp[i][k]=m ...
- P4983-忘情【wqs二分,斜率优化】
正题 题目链接:https://www.luogu.com.cn/problem/P4983 题目大意 给出长度为\(n\)的序列\(x\),记平均数为\(\bar{x}\),要求将序列分成\(m\) ...
- 洛谷P4983 忘情 (WQS二分+斜率优化)
题目链接 忘情水二分模板题,最优解对划分段数的导数满足单调性(原函数凸性)即可使用此方法. 详细题解洛谷里面就有,不啰嗦了. 二分的临界点让人有点头大... #include<bits/stdc ...
- 决策单调性&wqs二分
其实是一个还算 trivial 的知识点吧--早在 2019 年我就接触过了,然鹅当时由于没认真学并没有把自己学懂,故今复学之( 1. 决策单调性 引入:在求解 DP 问题的过程中我们常常遇到这样的问 ...
- wqs二分
今天模拟赛有一道林克卡特树,完全没有思路 赛后想了一想,不就是求\(k+1\)条不相交的链,使其权值之和最大嘛,傻了. 有一个最裸的\(DP\),设\(f[i][j][k]\)表示在以\(i\)为根的 ...
- For循环将将数字集合分类写入字典
有以下数字集合[11,22,33,44,55,66,77,88,99,25,35,45,66,88],将所有大于66的值保存至字典的第一个key中,将小于66的值保存至第二个key的值中.即{'k1' ...
- C#,判断数字集合是否是连续的
/// <summary> /// 判断数字集合是否是连续的 /// </summary> /// <returns></returns> public ...
- SCUT - 289 - 小O的数字 - 数位dp
https://scut.online/p/289 一个水到飞起的模板数位dp. #include<bits/stdc++.h> using namespace std; typedef ...
- Codeforces Round #365 (Div. 2) C - Chris and Road 二分找切点
// Codeforces Round #365 (Div. 2) // C - Chris and Road 二分找切点 // 题意:给你一个凸边行,凸边行有个初始的速度往左走,人有最大速度,可以停 ...
随机推荐
- 1.Linux命令行快捷键、Vim
1. 命令终端的快捷键使用 ctrl+b 左移光标 ctrl+f 右移光标 ctrl+u 删除光标左边的内容 ctrl+k 删除光标右边的内容 ctrl+w 删除光标前的一个单词 =esc+ctrl+ ...
- Mybatis 并发执行导致cpu占满的问题
最近线上服务经常 出现cpu达到100%的问题,发现都是执行oracle操作的方法就没有返回.经过排查,最后定位到cpu消耗在以下方法 System.Collections.Generic.Dicti ...
- CSS3实现三角形和对话框
这是最终实现的效果,类似于微信对话框的样式. 分析一下这个对话框的结构,由一个小三角形和一个长方形构成.长方形很容易就可以实现,重点是如何用CSS3做出一个小三角形. 一.如何生成一个三角形 总结: ...
- slick轮播图使用大全
let oSlick = { dom: null, isMobile: false, slickInited: false, barInterval:null, currentSlide:, last ...
- mysql FULL JOIN关键字 语法
mysql FULL JOIN关键字 语法 作用:只要其中某个表存在匹配,FULL JOIN 关键字就会返回行.“富瑞华”牌大理石构件 语法:SELECT column_name(s) FROM ta ...
- 随机森林(Random Forest,简称RF)和Bagging算法
随机森林(Random Forest,简称RF) 随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learn ...
- 使用xshell远程连接Linux
Linux系统对于程序员来说并不陌生,对IT技术员来说是一个很好的开发平台,因此掌握Linux系统的操作对于一个程序员来说非常有用.而对于习惯使用windows的人来说直接在Linux系统下进行操作感 ...
- 11 November
Weakness 求数列区间 \(\{a_n\}\) 中满足 \(i < j < k, a_i > a_j > a_k\) 的 \((i, j, k)\) 对的数目. 设对 \ ...
- 微信小程序之登录用户不是该小程序的开发者
当uniapp项目转为小程序项目的时候,预览会显示“您不是登录用户...”,所以没有办法发布,这个时候打开“project.config.json”设置一下appid,与你公众号appid一致就可以
- sqlserver 获取存储过程执行时间
use [数据库名] select last_execution_time '最近一次执行时间' from sys.dm_exec_procedure_stats where type='P' ...