传送门


解题思路

第一种

对于选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. centos .7x service iptables save 错误解决方案

    保存转发规则的时候,发现service iptables save 无效,而且报错[root@localhost bin]# service iptables saveThe service comm ...

  2. python学习相关软件安装

    爬虫初学者必装的软件!! 一.安装python step1:安装包下载 1.1.官网下载地址:https://www.python.org/ 根据自己电脑系统选择,我选择windowns 有不同版本可 ...

  3. 51nod1790 输出二进制数

    题目描述 题解 过于真实 LJ卡常题 一个显然的dp: 设f[i][j]表示做完前i个,最后一段为j+1~i的方案(最小值同理) 那么f[i][j]=min(f[i-j-1][k]),其中k~j-1要 ...

  4. linux运维、架构之路-linux目录结构

    1.linux重要目录 重要目录 说明 /etc 存放系统配置文件.服务启动命令的目录 /root 超级管理员的家目录 /sbin和usr/sbin 超级用户命令的目录 /boot 系统引导程序所在的 ...

  5. POJ 2385 Apple Catching ( 经典DP )

    题意 : 有两颗苹果树,在 1~T 的时间内会有两颗中的其中一颗落下一颗苹果,一头奶牛想要获取最多的苹果,但是它能够在树间转移的次数为 W 且奶牛一开始是在第一颗树下,请编程算出最多的奶牛获得的苹果数 ...

  6. 20180827(02)- Java发送邮件

    Java 发送邮件 使用Java应用程序发送E-mail十分简单,但是首先你应该在你的机器上安装JavaMail API 和Java Activation Framework (JAF) . 你可以在 ...

  7. php简单随机实现发红包程序

    前言: 使用PHP发红包,当我们输入红包数量和总金额后,PHP会根据这两个值进行随机分配每个金额,保证每个人都能领取到一个红包,每个红包金额不等,就是要求红包金额要有差异,所有红包金额总额应该等于总金 ...

  8. scipy几乎实现numpy的所有函数

    NumPy和SciPy的关系?   numpy提供了数组对象,面向的任何使用者.scipy在numpy的基础上,面向科学家和工程师,提供了更为精准和广泛的函数.scipy几乎实现numpy的所有函数, ...

  9. React-Native 之 GD (二)自定义共用导航栏样式

    1.自定义导航栏样式 步骤一:从效果图中可以看出,导航栏的样式都差不多,因为我们前面已经设置了 Navigator ,这边的话我们还需要自定义 Navigator 的样式,可以看到所有的 Naviga ...

  10. UVA 1380 A Scheduling Problem

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...