洛谷 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章