• 洛谷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]));//两种情况 
        }
        
    }
  • 相关阅读:
    表单工具可以什么
    页面嵌套的方式展现报表
    EChars图类型
    SVG图类型
    JSP <c:import>和<jsp:include>区别【转】
    Servlet配置
    jsp的scope属性【转载】
    Cookie、Session【转载】
    page、request、session、application区别【转载】
    C++笔记------static 和 const 在类中用法
  • 原文地址:https://www.cnblogs.com/lcezych/p/11124693.html
Copyright © 2020-2023  润新知