沙雕贪心......

我一开始想的是倒着来,每次减去一个。

然后我们就有两个决策:去掉最后一个/去掉前面某一个。

然后第一个决策用并查集维护,第二个决策用线段树即可。仔细想想觉得普及组不会考这种东西,慌得一批。

然后又发现可能有问题:你可能取x个的时候不从x + 1转移过来,而是x + 2

然后就不会了。

然后看提解发现正解是顺着来......什么沙雕。

结论:若取x个的时候最优解是集合S,那么取x+1个时的最优解集合一定包含S。(说明了上面我的做法是对的)

证:

即证对于每一个取x+1的方案p,若不包含S,都可以找到一个包含S的方案比它更优。

设取x个的最优方案为r

考虑最右那一个:

①p的最后那个等于r的最右那一个时,前面我们随便去掉一个不与r配对的位置d,然后p一定还与r不同。

我们把p调整成r,然后加上d,这样就比原来的p更优了。

②p的最后那个小于r的最后那一个时,我们同样去掉一个d,然后调整,最后加上d,就会更优。

③p的最后那个大于r的最后那个时,把p的最后那个去掉,同时p的价值减去(2 * 从r最后到p最后的距离)。

这样就相当于情况①中去掉d之后的p了。

然后调整成r之后把原来p的最后加上,再加上减去的价值,就会比原来的p更优。

 #include <cstdio>
#include <algorithm>
#include <queue> const int N = ; int a[N], x[N], g[N];
std::priority_queue<int> Q; int main() {
int n;
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
x[i] <<= ;
}
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
} for(int i = n; i >= ; i--) {
if(x[i] + a[i] > x[g[i + ]] + a[g[i + ]]) {
g[i] = i;
}
else {
g[i] = g[i + ];
}
} int now = g[]; int ans = a[now] + x[now], pos = ;
printf("%d\n", ans); for(int i = ; i <= n; i++) {
while(pos < now) {
Q.push(a[pos]);
pos++;
}
if(pos == now) {
pos++;
}
if(!Q.empty() && Q.top() > a[g[now + ]] + x[g[now + ]] - x[now]) {
ans += Q.top();
Q.pop();
}
else {
ans -= x[now];
now = g[now + ];
ans += a[now] + x[now];
}
printf("%d\n", ans);
} return ;
}

AC代码

然后我又打了一开始那个线段树的想法......

 #include <cstdio>
#include <algorithm>
#include <queue> const int N = , INF = 0x3f3f3f3f; int a[N], x[N], ans[N];
int small[N << ], fa[N]; int find(int x) {
if(fa[x] == x) {
return x;
}
return fa[x] = find(fa[x]);
} inline void pushup(int o) {
int ls = o << ;
int rs = ls | ;
if(a[small[ls]] <= a[small[rs]]) {
small[o] = small[ls];
}
else {
small[o] = small[rs];
}
return;
} void build(int l, int r, int o) {
if(l == r) {
small[o] = r;
return;
}
int mid = (l + r) >> ;
build(l, mid, o << );
build(mid + , r, o << | );
pushup(o);
return;
} int ask(int L, int R, int l, int r, int o) {
if(L <= l && r <= R) {
return small[o];
}
int mid = (l + r) >> ; if(R <= mid) {
return ask(L, R, l, mid, o << );
}
if(mid < L) {
return ask(L, R, mid + , r, o << | );
} int as = ask(L, R, l, mid, o << );
int t = ask(L, R, mid + , r, o << | );
if(a[t] < a[as]) {
as = t;
}
return as;
} void change(int p, int l, int r, int o) {
if(l == r) {
a[r] = INF;
return;
}
int mid = (l + r) >> ;
if(p <= mid) {
change(p, l, mid, o << );
}
else {
change(p, mid + , r, o << | );
}
pushup(o);
return;
} int main() {
int n, sum = ;
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &x[i]);
x[i] <<= ;
}
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
fa[i] = i;
sum += a[i];
}
sum += x[n];
ans[n] = sum; build(, n, ); int now = n;
for(int i = n - ; i >= ; i--) {
int pos = ask(, now - , , n, );
if(a[now] + x[now] - x[find(now - )] > a[pos]) {
sum -= a[pos];
change(pos, , n, );
fa[pos] = find(pos - );
}
else {
sum -= (a[now] + x[now] - x[find(now - )]);
now = find(now - );
}
ans[i] = sum;
} for(int i = ; i <= n; i++) {
printf("%d\n", ans[i]);
}
return ;
}

AC代码

话说这个代码我调都没调,一次就写对了。

洛谷P2672 推销员的更多相关文章

  1. 洛谷 P2672 推销员 解题报告

    P2672 推销员 题目描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有N家住户,第i家住户到入口的距离为 ...

  2. 洛谷P2672 推销员 题解 贪心

    题目链接:https://www.luogu.org/problem/P2672 这道题目是贪心,贪心的思想是: 选择 \(m\) 户人家的最大疲劳值应该是以下两种方案中的较大值: 方案一:选择 \( ...

  3. 洛谷 P2672 推销员

    题目传送门 解题思路: 我们会发现本题有一个特性,就是如果我们走到一个更远的地方,那么近的地方距离原点的距离我们可以忽略. 本题要求最大的疲劳值,所以我们需要排序,第一个想到堆,反正我是先想到堆. 然 ...

  4. 洛谷p2672推销员题解

    日常扯废话: 话说题解里的思路都写得真的是很奈斯啊 但是 代码看不懂确实让人头疼(可能是我太弱了) 就像题解里的第一篇题解代码简洁但是属实看不明白 趁着学姐刚给我讲了知识还热乎赶紧给泥萌说说哈 正文: ...

  5. 洛谷 P2672 推销员(贪心,模拟)

    传送门 解题思路 第一种: 对于选i家,很显然,a值前i-1家的一定会选,所以只需要考虑最后一家的选法.要么是选择a值第i大的(就不管s了),要么选择剩下的中s最大的. 我们把每一家的情况(s和a)存 ...

  6. 【洛谷 p2672】推销员

    推销员[题目链接] 好了为了凑字数先把题目复制一下: 好了题解第一篇正解: 首先输入,莫得什么好说的: scanf("%d",&n); ;i<=n;i++) scan ...

  7. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  8. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  9. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

随机推荐

  1. C# httpRequest Soap请求

    一般添加web服务引用是.NET用代理类模式 创建SOAP请求代理类,代理类是.NET开发工具VS自动给你生成. 下面用一般HTTP的模式有时候可能更合适,原理是构造SOAP请求的XML后POST过去 ...

  2. 20155233 Exp1 PC平台逆向破解(5)M

    Exp1 PC平台逆向破解(5)M 实践一 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数. 步骤 1.cp pwn1 pwn20155233拷贝pwn1文件,命名为pwn201 ...

  3. 20155311《网络对抗》MSF基础应用

    20155311<网络对抗>MSF基础应用 实验过程 实验系统 靶机1:Windows XP Professional SP2 ,IP地址:192.168.136.129 靶机2:Wind ...

  4. 《图说VR入门》——入门汇总

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53818922 作者:car ...

  5. [2016北京集训试题15]cot-[分块]

    Description Solution 如图,假如我们知道了以任何一个点为顶点的135-180度的前缀和和90-180度的前缀和,我们就可以搞出三角形的面积. 差分.add[i][j]和dev[i] ...

  6. 第五节 HTML&CSS -- 关于浮动和清除浮动的解说,以及两个大坑不要踩

    1.随便唠叨几句   这一节课我会对浮动元素和怎样清除浮动相关的技术进行一个讲解,同时,我会列举一些我们前端开发中常见的坑,希望大家以后不要在这些地方犯错.在开始今天的课程之前,有一个东西我需要先讲一 ...

  7. 内存和CPU资源控制

    数据库系统的资源是指内存和CPU(处理器)资源,拥有资源的多寡,决定了数据查询的性能.当一个SQL Server实例上,拥有多个独立的工作负载(workload)时,使用资源管理器(Resource ...

  8. 自动化部署-Jenkins+SVN+MSBuild 一些补充

    1.ftp的使用 系统管理->插件管理 安装插件Publish Over FTP 系统管理->系统设置 配置ftp参数 如下图 进入任务配置,添加构建后操作 在使用过程中还遇到一个本地防火 ...

  9. 查看Python的版本、内建方法和模块等内容的方法

    若想更好地应用Python帮助我们解决日常生活的问题,就必须了解清楚它的内建方法和模块等特性.相信不少同学在安装某个版本的Python后,对于内建方法之类都是一知半解,希望本文能帮助了解Python的 ...

  10. 机器学习1—简介及Python机器学习环境搭建

    简介 前置声明:本专栏的所有文章皆为本人学习时所做笔记而整理成篇,转载需授权且需注明文章来源,禁止商业用途,仅供学习交流.(欢迎大家提供宝贵的意见,共同进步) 正文: 机器学习,顾名思义,就是研究计算 ...