Solution to a problem P1484 [trees]

Topic Link

Solution to plant trees

Title effect: Given a length \ (n-\) is the number of columns, you can select more than \ (K \) number, such that no two adjacent numbers, and seeking the maximum weight

Analysis: We can easily think of a \ (O (nk) \) complexity \ (DP \) , but not very good optimization

In a similar induction ideas to consider:

When \ (k = 1 \) , the apparent \ (ans = max \ {a_i \} \)

When \ (k = 2 \) , we have two options:

  • Select the maximum and \ (a_i \) is not adjacent \ (a_j \)
  • 选择\ (a_ {i - 1} \) OR \ (a_ {i _ + 1 } \)

To prove that when \ (k = 2 \) when: \ (I -. 1 \) and \ (i + 1 \) either simultaneously selected, simultaneously or unsuccessful.

Reductio ad absurdum is easy to prove: only choose one time is not the optimal solution

Simultaneously selected: \ (A_ {I - A_. 1} + {I}. 1 + \)

At the same time unsuccessful: \ (a_i + a_j \)

Only a selected \ (A_. 1} + I {a_j + \) ( \ (A_ {I -. 1} \) Similarly)

Assuming that only a selected time is the optimal solution:

\(\therefore\)
\(a_{i + 1} + a_j > a_{i - 1} + a_{i + 1}\)

\ (A_. 1} + I {a_j +> a_i a_j + \)
(and \ (a_ {i + 1} \) not adjacent \ (a_j \) must not be the \ (a_i \) adjacent to, or \ (J = I -. 1 \) , in other words, two \ (a_j \) is the same number (maximum value because greedy))

\(\therefore\)

\(a_j > a_{i - 1}\)

\ (A_ +. 1 {I}> {I} A_ \) (not legal, contrary to the \ (k = 1 \) greedy at)

So we go first \ (k = 1 \) when the maximum \ (a_i \) , which corresponds to the number two cases are unsuccessful, in order to avoid leakage solution, we need to consider the case of two numbers are selected

We found that: If you select \ (a_ {i - 1} \) and \ (a_ {i + 1} \) , then our profit has increased by \ (a_ {i - 1} + a_ {i + 1 } - a_i \) , which can be back into the pile, the way \ (a_ {i - 1} \) and \ (a_ {i + 1} \) marked with numerals to avoid repeating selected (they are selected the new situation has been represented by a point)

Repeat this process, we use a doubly linked list to hold the point about each point, when the top of the heap is negative to the end

#include <cstdio>
#include <cctype>
#include <queue>
using namespace std;
const int maxn = 5e5 + 100;
inline int read(){
    int x = 0,f = 1;char c = getchar();
    while(!isdigit(c))f = c == '-' ? -1 : 1,c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x * f;
}
int l[maxn],r[maxn],vis[maxn],v[maxn],n,k;
long long ans;
struct HeapNode{
    int pos,val;
    bool operator < (const HeapNode &rhs)const{
        return val < rhs.val;
    }
};
priority_queue<HeapNode> Q;
int main(){
    n = read(),k = read();
    for(int i = 1;i <= n;i++)
        Q.push(HeapNode{i,read()}),l[i] = i - 1,r[i] = i + 1;
    l[0] = 1,r[n + 1] = n; 
    while(k--){
        while(vis[Q.top().pos])Q.pop();
        HeapNode h = Q.top();Q.pop();
        if(h.val < 0)break;
        ans += h.val;
        int now = h.pos;
        v[now] = v[l[now]] + v[r[now]] - v[now];
        h.val = v[now];
        vis[l[now]] = vis[r[now]] = 1;
        l[now] = l[l[now]];r[l[now]] = now;
        r[now] = r[r[now]];l[r[now]] = now;
        Q.push(h);
    }
    return printf("%lld\n",ans),0;
}

Guess you like

Origin www.cnblogs.com/colazcy/p/11515147.html