洛谷 P1484 种树

洛谷 P1484 种树

Description

  • cyrcyr今天在种树,他在一条直线上挖了n个坑。这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树。而且由于cyrcyr的树种不够,他至多会种k棵树。假设cyrcyr有某种神能力,能预知自己在某个坑种树的获利会是多少(可能为负),请你帮助他计算出他的最大获利。

Input

  • 第一行,两个正整数n,k。

    第二行,n个正整数,第i个数表示在直线上从左往右数第i个坑种树的获利。

Output

  • 输出1个数,表示cyrcyr种树的最大获利。

Sample Input

6 3 

100 1 -1 100 1 -1

Sample Output

200

Data Size

  • 对于20%的数据,n<=20。

    对于50%的数据,n<=6000。

    对于100%的数据,n<=500000,k<=n/2,在一个地方种树获利的绝对值在1000000以内。

题解:

  • 这题跟数据备份这题原理相同。都是利用数学归纳法。
#include <iostream>
#include <cstdio>
#include <set>
#define N 500005
#define int long long
using namespace std;

struct Node
{
    int pos, val;
    friend bool operator < (Node x, Node y) {
        if(x.val == y.val) return x.pos < y.pos;
        return x.val > y.val;
    }
};
int n, k, ans;
int a[N], l[N], r[N];
set<Node> st;

int read()
{
    int x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x *= f;
}

signed main()
{
    cin >> n >> k;
    for(int i = 1; i <= n; i++)
    {
        a[i] = read();
        st.insert((Node){i, a[i]});
        l[i] = i - 1, r[i] = i + 1;
    }
    a[0] = a[n + 1] = -0x3f3f3f3f;
    for(int i = 1; i <= k; i++)
    {
        int val = (*st.begin()).val;
        int pos = (*st.begin()).pos;
        if(val <= 0) {cout << ans; return 0;}
        ans += val;
        //删掉堆中的pos和l[pos]和r[pos]
        st.erase(st.begin());
        st.erase((Node){l[pos], a[l[pos]]});
        st.erase((Node){r[pos], a[r[pos]]});
        //添加新元素
        a[pos] = a[l[pos]] + a[r[pos]] - a[pos];
        st.insert((Node){pos, a[pos]});
        l[pos] = l[l[pos]], r[l[pos]] = pos;
        r[pos] = r[r[pos]], l[r[pos]] = pos;
    }
    cout << ans;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章