• [NOIp2015普及组]推销员


    OJ题号:洛谷P2672

    思路:

    贪心。每次把住户分为左右两部分。对于左边,每次的代价为$a_i$。对于右边,每次增加的代价为$s_i*2+a_i$。每次挑代价最大的住户加到答案中。

    60分代码:直接暴力贪心(初二上学期写的代码,所以是 Pascal )。

     1 uses
     2     math;
     3 var
     4     n,i,j,t:longint;
     5     s,a:array[1..100000]of longint;
     6     f,d:array[boolean]of longint;
     7     b:array[1..100000]of boolean;
     8 begin
     9     readln(n);
    10     for i:=1 to n do begin
    11         read(s[i])
    12     end;
    13     readln;
    14     for i:=1 to n do begin
    15         read(a[i])
    16     end;
    17     readln;
    18     fillchar(f,sizeof(f),0);
    19     fillchar(d,sizeof(d),0);
    20     fillchar(b,sizeof(b),0);
    21     for i:=1 to n do begin
    22         for j:=1 to n do begin
    23             if f[odd(i)]<(f[not odd(i)]+a[j]+max(s[j]-d[not odd(i)],0)<<1)*longint(not b[j]) then begin
    24                 f[odd(i)]:=f[not odd(i)]+a[j]+max(s[j]-d[not odd(i)],0)<<1;
    25                 d[odd(i)]:=max(s[j],d[not odd(i)]);
    26                 t:=j
    27             end
    28         end;
    29         b[t]:=true;
    30         writeln(f[odd(i)])
    31     end
    32 end.

    AC代码:优先队列优化。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<utility>
     4 #include<ext/pb_ds/priority_queue.hpp>
     5 __gnu_pbds::priority_queue<std::pair<int,int> > l,r;
     6 int main() {
     7     int n;
     8     scanf("%d",&n);
     9     int s[n],a[n];
    10     bool u[n];
    11     memset(u,0,sizeof u);
    12     for(int i=0;i<n;i++) scanf("%d",&s[i]);
    13     for(int i=0;i<n;i++) scanf("%d",&a[i]);
    14     for(int i=0;i<n;i++) r.push(std::make_pair(s[i]*2+a[i],i));
    15     int ans=0;
    16     for(int i=0;i<n;i++) {
    17         while(!r.empty()&&u[r.top().second]) r.pop();
    18         if(!l.empty()&&!r.empty()) {
    19             if(l.top().first>r.top().first) {
    20                 ans+=l.top().first;
    21                 l.pop();
    22             }
    23             else {
    24                 ans+=r.top().first;
    25                 u[r.top().second]=true;
    26                 for(int i=0;i<r.top().second;i++) {
    27                     if(u[i]) continue;
    28                     u[i]=true;
    29                     l.push(std::make_pair(a[i],i));
    30                 }
    31                 r.pop();
    32             }
    33             goto Ans;
    34         }
    35         if(l.empty()) {
    36             ans+=r.top().first;
    37             u[r.top().second]=true;
    38             for(int i=0;i<r.top().second;i++) {
    39                 if(u[i]) continue;
    40                 u[i]=true;
    41                 l.push(std::make_pair(a[i],i));
    42             }
    43             r.pop();
    44             goto Ans;
    45         }
    46         if(r.empty()) {
    47             ans+=l.top().first;
    48             l.pop();
    49         }
    50         Ans:
    51             printf("%d
    ",ans);
    52     }
    53     return 0;
    54 }

    另外本题还有线段树、树状数组等方法可以AC。

  • 相关阅读:
    冗余链接-684-并查集
    Chrome浏览器进程
    BFC布局规则
    Front-end 前端优化总结
    Flex弹性布局
    Browse兼容性问题
    组合关系与组合模式
    YUI3组件框架之plugin
    javascript数据类型及转换
    矩阵打印
  • 原文地址:https://www.cnblogs.com/skylee03/p/6861922.html
Copyright © 2020-2023  润新知