P2672 推销员

描述:https://www.luogu.com.cn/problem/P2672

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

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


结果这不过是普及组的一道题目,我好菜啊~
这道题的话住户有A(积累的疲劳值)和 S(距离)这两个因素
现在假设我们选了A值前X大的X人
我们现在如果还想提高疲劳值,该怎么做?只能在距离上做功夫。
我们可以试着舍弃一个A值最小的,去找一个距离更大住户。
但是却不用舍弃两个
因为已经从大到小排序了,所以,如果舍去2个疲劳值,那么后面只会在加上两个更小的疲劳值,以及两个之间最大的距离并乘2,那么这样还不如只舍去一个。
那么结论已经出来了
对于每个x,一定是选择(一个最大的s)+(x-1个最大的a)或者x个最大的a,可以使答案最优
#include <bits/stdc++.h>
using namespace std;
struct p{
    int s,v;
}a[100009];
int sumn[100009],h[100009],qm[100009];
bool com(p a,p b){
    return a.v>b.v;
}
int main()
{
    int n;
    cin>>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+1+n,com);
    for(int i=1;i<=n;i++)
    sumn[i]=sumn[i-1]+a[i].v,qm[i]=max(qm[i-1],a[i].s);//前x项距离的最大值 
    for(int i=n;i>=1;i--)
        h[i]=max(h[i+1],2*a[i].s+a[i].v);
    for(int i=1;i<=n;i++)
        cout<<max(sumn[i]+qm[i]*2,sumn[i-1]+h[i])<<endl;
}
原文地址:https://www.cnblogs.com/iss-ue/p/12536530.html