• 洛谷P2672 推销员


    先看标签。线段树,树状数组(滚蛋),贪心(海星),所以选择贪心做;

    话说他想要疲劳值最大直接一直走不就行了qwq

    考虑虑i的最大疲劳值一定是选择i个val最大的或者是i-1个val最大的和一个s较大的(之所以不是最大的是因为val还会产生影响) 

    所以我们把这些住宅按照val排序

    在选择i个val最大的情况下,产生的疲劳值就是前i个val的和加上两倍的最大距离(前i个物品之间的)

    在选择i-1个val最大的和一个s较大的情况下,我们考虑从后往前枚举2*s+val的最大值,然后在加上前i-1个val的和就可以了

    所以我们考虑预处理一下,设h[i]表示后i个2*s+val的最大值 ,q[i]表示前i个距离最大值,sum[i]表示前i个val的和

    最后第i项的答案就是max(sum[i-1]+h[i],sum[i]+2*q[i])了

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    //考虑i的最大价值一定是选择所有val最大的或者是i-1个val最大的和一个s较大的 
    
    struct home
    {
        int s,val;
    }a[100005];
    
    int n;
    
    inline bool cmp(home a,home b)
    {
        return a.val>b.val;
    }
    
    int sum[100005],q[100005],h[100005];
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) a[i].s=read();
        for(int i=1;i<=n;i++) a[i].val=read();
        sort(a+1,a+1+n,cmp);
        for(int i=n;i>=1;i--)
        {
            h[i]=max(h[i+1],2*a[i].s+a[i].val);//后i个2*a[i].s+a[i].val的最大值 
        }
        for(int i=1;i<=n;i++)
        {
            q[i]=max(q[i-1],a[i].s);//前i个距离最大值 
            sum[i]=sum[i-1]+a[i].val;//前i个val的和 
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d
    ",max(sum[i-1]+h[i],sum[i]+2*q[i]));//两种情况 
        }
        
    }
  • 相关阅读:
    第23条:通过委托与数据源协议进行对象间通信
    第22条:理解NSCopying协议
    第21条:理解Objective-C错误模型
    第20条:为私有方法名加前缀
    《隐藏键盘》《隐藏PickerView控键》如果是xib中 点击空白处隐藏键盘
    《弹出提示》UIAlertView 弹出提示
    MAC 问题。
    小技巧
    控制器的生命周期
    问题。控制器跳转
  • 原文地址:https://www.cnblogs.com/lcezych/p/11124693.html
Copyright © 2020-2023  润新知