~~~题面~~~

题解:

我会说我想这道普及组题都想了好久么。。。。

不熟练的普及组选手.jpg

最后随便猜了一个结论居然是对的。。。

放结论:

假设x = i的最优决策为f[i], 那么f[i + 1]一定包括f[i].

也就是说f[i+1]一定可以由f[i]推出来。

所以f[i]一定是由f[i+1]中选定的所有点中去掉一个得来的。

即下一次选择一定是基于上一次选择的。。。

至于证明嘛。。。感性理解吧。

因为选哪户人家推销其实相互没太多联系。而且选i个推销肯定选满是最划得来的。。。。

大概是这么理解的吧。(反向理解可能更加好理解一点)

所以有了这个结论就很好解决了。

因为f[n]的最优决策肯定是n个点全选。

所以我们从这个已知的往前推。

于是我们来观察这n个点,到底删掉哪个减掉的疲劳值最小呢?

首先选中的这些点可以看做一个有序点集,位置由s[i]的大小所决定。

因此我们记last[x]为在x前面的第一个点的id, Next[x]为在x后面的第一个点的id。

于是有两种情况:

1,删去的点在末尾。

  此时减掉的疲劳值为a[x] + 2 * (s[x] - s[last[x]])

2,删去的点在中间。

  那么此时对走路的距离没有任何影响,因此我们只需要减a[x]即可。

值得注意的是,当末尾点k为a[i]最小的点时, 我们需要再取出次小的点来做比较,因为a[k]虽然最小,但由于要走很多路,所以a[k] + 2 * (s[k] - s[last[k]])并不一定小于a[i](i < k, 且i ∈ 点集),因此我们需要进一步比较再做取舍。

而k不是a[i]最小的点时,因为a[k]就已经大于a[i]了,所以减去的疲劳值肯定要大于a[i]了,因此直接删最小的点就可以了。

这里的最小和次小由于要支持插入,删除,查询,因此我们使用优先队列来实现。

为了方便查询元素的id,,,于是我又建了一个结构体、。

代码:

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define LL long long
#define getchar() *o++
#define AC 100100
char READ[], *o = READ;
int n;
int s[AC], a[AC], ans[AC], Next[AC], last[AC], r;
struct node{
int w, id;
}; struct cmp{
bool operator () (node a, node b)
{
return a.w > b.w;
}
}; priority_queue <node, vector<node>, cmp> q; inline int read()
{
int x = ; char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void pre()
{
n = read();
for(R i = ; i <= n; i++) s[i] = read();
for(R i = ; i <= n; i++)
{
a[i] = read();
q.push((node){a[i], i});
ans[n] += a[i];
last[i] = i - ;
if(i != n) Next[i] = i + ;
}
ans[n] += s[n] * , r = n;
} void work()
{
int b = n - ;node x, now;
for(R i = b; i; i--)
{
x = q.top();
if(x.id == r)
{
q.pop();
now = q.top();
if(now.w < x.w + (s[x.id] - s[last[x.id]]) * )
{
q.pop();
Next[last[now.id]] = Next[now.id];
last[Next[now.id]] = last[now.id];
ans[i] = ans[i + ] - now.w;
q.push(x);
}
else//不然就删后者
{
Next[now.id] = ;
ans[i] = ans[i + ] - x.w - * (s[x.id] - s[last[x.id]]);
r = last[x.id];//移动末项
}
}
else//不然直接就删中间的了
{
q.pop();
Next[last[x.id]] = Next[x.id];
last[Next[x.id]] = last[x.id];
ans[i] = ans[i + ] - x.w;
}
}
for(R i = ; i <= n; i++) printf("%d\n", ans[i]);
} int main()
{
freopen("in.in", "r", stdin);
fread(READ, , , stdin);
pre();
work();
fclose(stdin);
return ;
}

P2672 推销员 优先队列 + 贪心的更多相关文章

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

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

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

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

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

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

  4. P2672 推销员(已经补锅)

    P2672 推销员 下面讲正确的贪心 题解 考虑当推销员要推销 i 家客户时,他可以有两种选择: (1)选择前 i 家疲劳值 a 最大的客户,加上这些客户里最远的距离 (2)选择前 i-1 家疲劳值 ...

  5. 最高的奖励 - 优先队列&贪心 / 并查集

    题目地址:http://www.51cpc.com/web/problem.php?id=1587 Summarize: 优先队列&贪心: 1. 按价值最高排序,价值相同则按完成时间越晚为先: ...

  6. POJ2431 优先队列+贪心 - biaobiao88

    以下代码可对结构体数组中的元素进行排序,也差不多算是一个小小的模板了吧 #include<iostream> #include<algorithm> using namespa ...

  7. hdu3438 Buy and Resell(优先队列+贪心)

    Buy and Resell Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  8. [luoguP2672] 推销员(贪心 + 树状数组 + 优先队列)

    传送门 贪心...蒟蒻证明不会... 每一次找最大的即可,找出一次最大的,数列会分为左右两边,左边用stl优先队列维护,右边用树状数组维护.. (线段树超时了....) 代码 #include < ...

  9. luogu P2672 推销员 |贪心

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

随机推荐

  1. linux 解压命令大全[转]

    本文转自:  http://www.cnblogs.com/eoiioe/archive/2008/09/20/1294681.html .tar 解包:tar xvf FileName.tar打包: ...

  2. 浅析Win8/8.1下安装SQL Server 2005 出现服务项无法正常启动解决方案

    如何才能在微软最新的Windows8/Windows 8.1下正常使用SQL Server 2005套件呢?下面就简单介绍利用文件替换法,解决其服务项无法正常启动的临时方案.当然还是建议使用SQL S ...

  3. pygame安装【在pycharm的IDE project下】

    pygame安装[在pycharm的IDE project下] 首先更新电脑的pip.exe[命令行下面] 然后进入IDE project ——>setting 中查找是否安装pygame 我的 ...

  4. Qt-QML-Loader初步接触

    先说说为什么用到了QML的Loader,这里我就要先扯点别的,那就是QML自带的ColorDialog,QML的机制 是优先调用系统提供的ColorDialog,如果系统的ColorDialog的不可 ...

  5. gitlab-登录账户遇到ERROR: Permission to XXX.git denied to user报错怎么办

    碰到这个问题就意味着没有访问账户的权限,没有把访问电脑与访问账户用ssh_key关联起来,解决流程: 1.查看本地是否有ssh_key 笔者用的是git bash来输入命令 ls -al ~/.ssh ...

  6. Selenium WebDriver(Python)API

    1.通过示例介绍Selenium-WebDriver 一个简单的入门方法就是这个例子,它在Google上搜索术语“Cheese”,然后将结果页面的标题输出到控制台. java csharp pytho ...

  7. angular-列表进行添加、编辑等操作时此行变色。

    今天接触了一个功能,就是在一个列表中,当你新增或者对第N列进行编辑,删除等操作时这一列会变颜色.让用户对操作了哪行数据更认识更清晰,刷新之后这行的颜色就会消失.我觉得这个很有意思,记录一下.效果如下. ...

  8. C struct中的位域 bitfield

    C struct中的位域 bitfield 结构体的成员可以限制其位域,每个成员可以使用用比字节还小的取值范围,下面的结构体s1中,四个成员每个成员都是2bit的值(0~3),整个结构体占据的空间依然 ...

  9. 虚拟机下 rm -rf / 尝试

    环境:虚拟机 系统版本:centOS 5.8.centOS 6.5 1. root权限:rm -rf / 2. root权限:rm -rf /* 测试结果:5.8下执行命令1,2,根目录文件被删除,系 ...

  10. SGU 326 Perspective(最大流)

    Description Breaking news! A Russian billionaire has bought a yet undisclosed NBA team. He's plannin ...