• P1484 种树


    传送门

    瞄一眼

    显然DP

    再瞄一眼

    方程就出来了:

    设f[ i ][ j ]表示考虑到第 i 颗树,已经种了 j 颗的最大价值.

    则 f[ i ][ j ]=max(f[ i-1][ j ],f[ i-2 ][ j-1]+value[ i ]);

    最后看了眼数据..

    凉了....

    考虑优化

    想死也想不出来...........

    最后看了题解才懂...

    洛沽的题解(不是我的)


    贪心

    如果选择一个点种树

    那么它两边的点都不能种

    当只种 1 颗时

    如果选择第 i 个点最优,那就选 i 

    种 2 颗时,如果要放弃 i 而选 i 两边的点

    那么就一定要两点一起选

    因为如果放弃 i 后只选一边的点,那还不如选 i(因为i 的价值肯定大于一边的点,不然前面就不会选 i 了)

    而且选了旁边的点更旁边的点就不能选

    所以如果放弃 i 就一定要一起选旁边的两点

    显然 如果放弃 i 选旁边两点 那么增加的价值为:value[ i-1]+value[ i+1]-value[ i ]

    那么我们可以抽象地添加一个点 a ,a=value[ i-1]+value[ i+1]-value[ i ]

    如果选了 a 就表示放弃了 i 从而选 i 两边的点

    在什么时候添加点 a 呢

    显然是在选了点 i 以后..

    那么我们就可以贪心了:

    选最大的点,更新答案后扔掉,添加 a 到数列里

    再选最大的点,一直这样,直到选了 k 个点

    (就算选的是抽象出来的点也可以,原因很简单,稍微画个图就懂了)

    怎么维护也很简单

    开个结构体,用一个堆维护就好了

    剩下就是一些细节了,看程序就好了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    using namespace std;
    struct node
    {
        long long v,id;
        bool operator < (const node &b) const{
            return v<b.v;
        }
    };
    priority_queue <node> q;
    long long n,k,a[500007],l[500007],r[500007],ans;
    bool pd[500007];
    int main()
    {
        node p;
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            l[i]=i-1; r[i]=i+1;
            p.v=a[i]; p.id=i;
            q.push(p);
        }
        int x;
        while(k--)
        {
            while(pd[q.top().id]) q.pop();
            p=q.top(); q.pop();
            if(p.v<=0) break; //细节,如果出现负数就直接退出,选了反而更小
            ans+=p.v;
            x=p.id;
            a[x]=a[l[x]]+a[r[x]]-a[x];
            pd[l[x]]=pd[r[x]]=1;//细节
            l[x]=l[l[x]]; r[x]=r[r[x]];//细节
            r[l[x]]=x; l[r[x]]=x;//细节
            p.v=a[x];
            q.push(p);
        }//这里有一堆细节
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    JavaScript设计模式与开发实践——读书笔记1.高阶函数(下)
    JavaScript设计模式与开发实践——读书笔记1.高阶函数(上)
    js 去除字符串中的空格
    js 运算符 || && 妙用
    判断一个js对象是不是数组
    Javascript中的异步
    js异步处理工作机制(setTimeout, setInterval)
    移动端html页面优化
    编写高效的jQuery代码
    JavaScript学习笔记 isPrototypeOf和hasOwnProperty使用区别
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9533346.html
Copyright © 2020-2023  润新知