zoukankan      html  css  js  c++  java
  • 洛谷 P2672 推销员(贪心,模拟)

    传送门


    解题思路

    第一种

    对于选i家,很显然,a值前i-1家的一定会选,所以只需要考虑最后一家的选法。要么是选择a值第i大的(就不管s了),要么选择剩下的中s最大的。

    我们把每一家的情况(s和a)存入几个结构体中,按照a的值从大到小排序,再用sum求出a的前缀和,用maxs[i]表示前i家中最大的s,用maxa[i]表示在i...n家中选一家的最大价值,即(s*2+a)的最大值。

    然后对于要求的每一个i,ans[i]就是

    • 选a值最大的前i家
    • 选a值最大的前i-1家加上剩下的i...n家中贡献最大的那家

    中的最大值,即

    ans[i]=max(sum[i]+2*maxs[i],sum[i-1]+maxa[i]))。

    第二种:

    很显然,ans随着i的增大递增,所以用一个ans记录答案,每一次加上一个数。

    对于每一次选择,可以分为两种情况,设距离最远的一家的地址为now:

    • 选择地址<now的a值最大的那一家k,对答案的贡献为a[k]
    • 选择地址>now的对答案贡献最大的那一家k,对答案的贡献为a[k]+2*(s[k]-now)

    所以每次取max即可。

    这里用两个大跟堆来实现比较方便。

    q1存的是在now左面的点,q2存的是now右面的点。

    如果更新右面的点,就q2弹出去一个,然后把q1中加入所有坐标在now和q2.top()的坐标之间的点,最后更新now的值。

    如果更新的是左面的点,就q1弹出,q2不做处理。

    这样,在每次取q2中的点时,就要先弹出所有坐标小于now的点。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 using namespace std;
     6 const int maxn=100005;
     7 int n,maxs[maxn],maxa[maxn];
     8 struct node{
     9     int s,a;
    10     bool operator <(const node &xx) {
    11         return a>xx.a;
    12     }
    13 }x[maxn];
    14 int sum[maxn];
    15 int main()
    16 {
    17     cin>>n;
    18     for(int i=1;i<=n;i++){
    19         scanf("%d",&x[i].s);
    20     }
    21     for(int i=1;i<=n;i++){
    22         scanf("%d",&x[i].a);
    23     }
    24     sort(x+1,x+n+1);
    25     for(int i=1;i<=n;i++){
    26         sum[i]=sum[i-1]+x[i].a;
    27         maxs[i]=max(maxs[i-1],x[i].s);
    28     }
    29     for(int i=n;i>=1;i--){
    30         maxa[i]=max(maxa[i+1],2*x[i].s+x[i].a);
    31     }
    32     for(int i=1;i<=n;i++){
    33         printf("%d
    ",max(sum[i]+2*maxs[i],sum[i-1]+maxa[i]));
    34     }
    35     return 0;
    36 }
    第一种
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn=100005;
     7 int n;
     8 long long ans;
     9 struct node{
    10     int s;
    11     int a;
    12     bool operator<(const node &p) const{
    13         return 2*s+a<p.s*2+p.a;
    14     }
    15 }d[maxn]; 
    16 priority_queue<int> q1;
    17 priority_queue<node> q2; 
    18 void shuchu() {
    19     printf("%lld
    ",ans);
    20 }
    21 int main(){
    22     cin>>n;
    23     for(int i=1;i<=n;i++){
    24         scanf("%d",&d[i].s);
    25     }
    26     for(int i=1;i<=n;i++){
    27         scanf("%d",&d[i].a);
    28     }
    29     for(int i=1;i<=n;i++){
    30         q2.push(d[i]);
    31     }
    32     int now=0;
    33     for(int i=1;i<=n;i++){
    34         node d2;
    35         if(!q2.empty()){
    36             d2=q2.top();
    37             while(d2.s<now&&!q2.empty()) q2.pop(),d2=q2.top();
    38         }
    39         if(q1.empty()){
    40             node d2=q2.top();
    41             q2.pop();
    42             now=d2.s;
    43             ans+=d2.a+2*d2.s-2*now;
    44             shuchu();
    45             continue;
    46         }
    47         if(q2.empty()){
    48             int d1=q1.top();
    49             q1.pop();
    50             ans+=d1;
    51             shuchu();
    52             continue;
    53         }
    54         int d1=q1.top();
    55         int d22=d2.a+2*d2.s-2*now;
    56         if(d1>d22){
    57             q1.pop();
    58             ans+=d1;
    59         }else{
    60             q2.pop();
    61             now=d2.s;
    62             ans+=d22;
    63         }
    64         shuchu();
    65     }
    66     return 0;
    67 }
    第二种

    //NOIP2015普及组t4

  • 相关阅读:
    mongdb
    网络编程
    分布式锁与事务
    mongodb
    Angular4
    思考
    kafka
    Spark总结
    你不知道的javaScript笔记(1)
    vue2.0 配置 选项 属性 方法 事件 ——速查
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/11762167.html
Copyright © 2011-2022 走看看