传送门


解题思路

第一种

对于选i家,很显然,a值前i-1家的一定会选,所以只需要考虑最后一家的选法。要么是选择a值第i大的(就不管s了),要么选择剩下的中s最大的。

我们把每一家的情况(s和a)存入几个结构体中,按照a的值从大到小排序,再用sum求出a的前缀和,用maxs[i]表示前i家中最大的s,用maxa[i]表示在i...n家中选一家的最大价值,即(s*2+a)的最大值。

然后对于要求的每一个i,ans[i]就是

  • 选a值最大的前i家
  • 选a值最大的前i-1家加上剩下的i...n家中贡献最大的那家

中的最大值,即

ans[i]=max(sum[i]+2*maxs[i],sum[i-1]+maxa[i]))。

第二种:

很显然,ans随着i的增大递增,所以用一个ans记录答案,每一次加上一个数。

对于每一次选择,可以分为两种情况,设距离最远的一家的地址为now:

  • 选择地址<now的a值最大的那一家k,对答案的贡献为a[k]
  • 选择地址>now的对答案贡献最大的那一家k,对答案的贡献为a[k]+2*(s[k]-now)

所以每次取max即可。

这里用两个大跟堆来实现比较方便。

q1存的是在now左面的点,q2存的是now右面的点。

如果更新右面的点,就q2弹出去一个,然后把q1中加入所有坐标在now和q2.top()的坐标之间的点,最后更新now的值。

如果更新的是左面的点,就q1弹出,q2不做处理。

这样,在每次取q2中的点时,就要先弹出所有坐标小于now的点。

AC代码

 #include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxn=;
int n,maxs[maxn],maxa[maxn];
struct node{
int s,a;
bool operator <(const node &xx) {
return a>xx.a;
}
}x[maxn];
int sum[maxn];
int main()
{
cin>>n;
for(int i=;i<=n;i++){
scanf("%d",&x[i].s);
}
for(int i=;i<=n;i++){
scanf("%d",&x[i].a);
}
sort(x+,x+n+);
for(int i=;i<=n;i++){
sum[i]=sum[i-]+x[i].a;
maxs[i]=max(maxs[i-],x[i].s);
}
for(int i=n;i>=;i--){
maxa[i]=max(maxa[i+],*x[i].s+x[i].a);
}
for(int i=;i<=n;i++){
printf("%d\n",max(sum[i]+*maxs[i],sum[i-]+maxa[i]));
}
return ;
}

第一种

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=;
int n;
long long ans;
struct node{
int s;
int a;
bool operator<(const node &p) const{
return *s+a<p.s*+p.a;
}
}d[maxn];
priority_queue<int> q1;
priority_queue<node> q2;
void shuchu() {
printf("%lld\n",ans);
}
int main(){
cin>>n;
for(int i=;i<=n;i++){
scanf("%d",&d[i].s);
}
for(int i=;i<=n;i++){
scanf("%d",&d[i].a);
}
for(int i=;i<=n;i++){
q2.push(d[i]);
}
int now=;
for(int i=;i<=n;i++){
node d2;
if(!q2.empty()){
d2=q2.top();
while(d2.s<now&&!q2.empty()) q2.pop(),d2=q2.top();
}
if(q1.empty()){
node d2=q2.top();
q2.pop();
now=d2.s;
ans+=d2.a+*d2.s-*now;
shuchu();
continue;
}
if(q2.empty()){
int d1=q1.top();
q1.pop();
ans+=d1;
shuchu();
continue;
}
int d1=q1.top();
int d22=d2.a+*d2.s-*now;
if(d1>d22){
q1.pop();
ans+=d1;
}else{
q2.pop();
now=d2.s;
ans+=d22;
}
shuchu();
}
return ;
}

第二种

//NOIP2015普及组t4

洛谷 P2672 推销员(贪心,模拟)的更多相关文章

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

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

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

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

  3. 洛谷P2672 推销员

    沙雕贪心...... 我一开始想的是倒着来,每次减去一个. 然后我们就有两个决策:去掉最后一个/去掉前面某一个. 然后第一个决策用并查集维护,第二个决策用线段树即可.仔细想想觉得普及组不会考这种东西, ...

  4. 洛谷p2672推销员题解

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

  5. 洛谷 P6851 onu (贪心,模拟)

    题意:C和D打牌,每张牌有花色和点数,小D刚开始的分数为\(v\),不管输还是赢,只要小D出了牌(花色必须相同),就能得到那张牌点数的分数,若是赢了(点数不小于D的牌),他可以另外加\(c\)分,输了 ...

  6. 洛谷 P2672 推销员

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

  7. 洛谷 P3049 Landscaping ( 贪心 || DP)

    题意 : 有n块土地,每块有A[i]泥土,现把其改造成B[i]泥土,有3种操作:(1)花费X向任意土地增加1泥土:(2)花费Y向任意土地减少1泥土:(3)花费Z*|i-j|把土地i的1泥土运到土地j. ...

  8. 洛谷P1667/[10.22 模拟赛] 数列 (思维+模拟)

    洛谷P1667 数列 题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足\(A_X +A_{ ...

  9. 【洛谷 p2672】推销员

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

随机推荐

  1. 前端每日实战:16# 视频演示如何用纯 CSS 创作一个渐变色动画边框

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/odpRKX 可交互视频教程 此视频 ...

  2. C++ GUI Qt4学习笔记07

    C++ GUI Qt4   qtc++scrollobject编程 事件(event)是由串口系统或者Qt自身产生的,用以响应所发生的各类事情.当用户按下或者松开键盘或者鼠标上的按键时,就可以产生一个 ...

  3. 用设计模式来替代if-else

    前言 物流行业中,通常会涉及到EDI报文(XML格式文件)传输和回执接收,每发送一份EDI报文,后续都会收到与之关联的回执(标识该数据在第三方系统中的流转状态).这里枚举几种回执类型:MT1101.M ...

  4. 51nod1730 涂边

    题目描述 题解 八级sb题 显然可以想到状压 枚举当前的宽度\(I\),设\(f[s]\)表示在当前的宽度下选的竖边的状态为s 再设\(g[s1][s2]\)表示状态s1转移到s2的方案数,枚举中间横 ...

  5. webpack配置反向代理

    devServer: { contentBase: path.resolve(__dirname, "../dev"), compress: true, port: ,//本身的端 ...

  6. 死锁(deadlocks)

    1.定义 所谓死锁<DeadLock>: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象.若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了 ...

  7. 舞蹈课(dancingLessons)

    有n个人参加一个舞蹈课.每个人的舞蹈技术由整数ai来决定.在舞蹈课的开始,他们从左到右站成一排.当这一排中至少有一对相邻的异性时,舞蹈技术相差最小的那一对会出列并开始跳舞.如果相差最小的不止一对,那么 ...

  8. Anaconda-navigator 打不开的解决方法(亲测有效!)

    本文链接:https://blog.csdn.net/qq_42489092/article/details/92208822method_1:每当你打不开应用时,不妨试一下:用管理员身份运行 请用管 ...

  9. es的索引库模板

    在实际的生产中,如果要插入大批量数据的时候需要使用多个索引库,如果我们还是手工指定每个索引的配置信息settings和mappings,是非常耗时的: 针对这种情况,es有index template ...

  10. 【转】DataRow复制一行到另一个DataTable

     源地址:http://www.cnblogs.com/pains/archive/2007/11/22/969003.html   下面两个方法是DataRow复制一行到另一个DataTable的, ...