【NOIP2015】推销员

Description

阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有NN家住户,第ii家住户到入口的距离为S_iSi米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的XX家住户推销产品,然后再原路走出去。

阿明每走11米就会积累11点疲劳值,向第ii家住户推销产品会积累A_iAi点疲劳值。阿明是工作狂,他想知道,对于不同的XX,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

Solution

 

考虑我们如何将答案最大化:对于每个x,一定是选择(一个最大的s)+(x-1个最大的a)或者x个最大的a,可以使答案最优
我们先把数组按照a排序
我们用sum[i]表示a数组的前i项的和,lu[i]表示s数组的前i项的最大值,k[i]表示a[i]*2+s[i]后i项的最大值,
对于每个x,他的答案就是max(sum[x]+lu[i]*2,sum[x-1]+k[x])

Code

 

#include <bits/stdc++.h>
using namespace std;
int n;
int sum[100010], lu[100010], k[100010];
struct emmm
{
    int s, v;
} a[100010];
bool cmp(emmm a, emmm b) {
    return a.v > b.v;
}
int main() {
    ios::sync_with_stdio(false);
    cin >> n;//输入n
    for (int i = 1;i <= n; i++)
        cin >> a[i].s;
    for (int i = 1;i <= n; i++)
        cin >> a[i].v;
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1;i <= n; i++) {
        sum[i] = sum[i - 1] + a[i].v;
        lu[i] = max(lu[i - 1], a[i].s);
    }
    for (int i = n; i >= 1; i--)
        k[i] = max(k[i + 1], a[i].s * 2 + a[i].v);
    for (int i = 1;i <= n; i++)
        cout << max(sum[i] + lu[i] * 2, sum[i - 1] + k[i]) << endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/-sheldon/p/11408426.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值