• 洛谷 P1484 种树(优先队列,贪心,链表)


    传送门


    解题思路

    第一眼的贪心策略:每次都选最大的。

    但是——不正确!

    因为选了第i个树,第i-1和i-1棵树就不能选了。所以,要有一个反悔操作。

    选了第i个后,我们就把a[i]的值更新为a[l[i]]+a[r[i]]-a[i]。

    然后这样如果发现选i-1和i+1更优时,再次加上a[i],结果就变成了a[i]+a[l[i]]+a[r[i]]-a[i]=a[l[i]]+a[r[i]]。

    然后这时再更新l[i]和r[i],把左边和右边两个节点删去。

    因为每一次会比上一次多种一棵,所以循环k次,求一个ans即为答案。

    也许会有疑问,当i-1或i+1是负数时,不选这个负数明显更优,但是a[i-1]+a[i+1]是包含了这个负数的。

    其实我们考虑,当有一个是负数,且a[i-1]+a[i+1]>a[i]时,很显然是另一个正数大于a[i],而这个正数一定会比i这棵树先种,所以不必考虑这种情况。

    最后,当现在操作的最大利益已经是负数或零了,可以直接break掉,因为树是最大k棵。

    AC代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 using namespace std;
     5 const int maxn=500005;
     6 int n,k,l[maxn],r[maxn],a[maxn],vis[maxn];
     7 long long ans;
     8 struct node{
     9     int id,value;
    10     bool operator < (const node &x)const{
    11         return value<x.value; 
    12     }
    13     node(int a,int b):id(a),value(b){}
    14 };
    15 priority_queue<node> q;
    16 int main(){
    17     cin>>n>>k;
    18     for(int i=1;i<=n;i++){
    19         scanf("%d",&a[i]);
    20         l[i]=i-1;
    21         r[i]=i+1;
    22         q.push(node(i,a[i]));
    23     }
    24     r[0]=1;
    25     l[n+1]=n;
    26     while(k--){
    27         while(vis[q.top().id]){
    28             q.pop();
    29         }
    30         node x=q.top();
    31         q.pop();
    32         if(x.value<=0) break;
    33         ans+=x.value;
    34         int id=x.id;
    35         vis[l[id]]=vis[r[id]]=1;
    36         a[id]=a[l[id]]+a[r[id]]-a[id];
    37         x.value=a[id];
    38         r[l[l[id]]]=id;
    39         l[r[r[id]]]=id;
    40         l[id]=l[l[id]];
    41         r[id]=r[r[id]];
    42         q.push(x);
    43     }
    44     cout<<ans;
    45     return 0;
    46 }
  • 相关阅读:
    ssm框架中的struts我的配置问题
    ssm框架web.xml中filter配置问题
    partition-list
    entity.Student@150f3932, entity.Student@1a740c6b 没有实体中的数据
    UVA 11361 Investigating Div-Sum Property
    UVA 10883 Supermean
    Gym 101081K Pope's work
    UVA 1103 How Many O's?
    HOJ 1108
    HDU 5936 朋友
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12037283.html
Copyright © 2020-2023  润新知