P1484 trees - priority queue data structure

We planted a tree in the afternoon, and finally gave it out ((Thank you for the great God of problem solutions) (solution to a problem you can not speak clearly point (unseen unseen)));

K you have a tree, you can kind of in a straight line, each location has a value, if you put the trees where you can get this value, but conditions are not there any two adjacent trees;

Of course, you can plant any tree to k 0;

How to do it? This question is a (rare) problem conscience; I wrote the first 20 minutes without brain violence, enumerate this position selected or not selected;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
int n,k;
int a[maxn];
int b[maxn];
ll ans;
ll cnt;
void dfs(int x)
{
    if(x==n+1)
    {
        ll sum=0;
        int num=0;
        for(int i=1;i<=n;i++)
        {
            if(b[i]==1&&b[i-1]==1) return ;
            if(b[i]==1) 
            {
                num++;
                if(num>k) return ;
                sum+=(ll)a[i];
            }
        }
        ans=max(ans,sum);
        return ;
    }
    b[x]=0;dfs(x+1);
    b[x]=1;dfs(x+1);
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    dfs(1);
    printf("%lld",ans);
    return 0;
}

But how can you willing to 20 points, think this is a straight line, you may use dp, just paste a pass by 50 points;

It is f [i] [j] indicates the current position a total of from 1 to i j tree planted maximum value;

If the current is not trees, direct copying f [i-1] [j], if they wish trees, is copied f [i-2] [j-1] (because it is not adjacent)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
int n,k;
ll a[maxn];
ll ans;
ll f[6010][3010];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    f[1][1]=a[1];
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            f[i][j]=max(f[i-1][j],f[i-2][j-1]+a[i]);
            ans=max(ans,f[i][j]);
        }
    }
    printf("%lld",ans);
    return 0;
}

Space-time constraints, I can not get out of, oh good gas;

Finally, I opened the solution to a problem (eyes emit light)

three months later……

We do not control what kinds of whoever who the latter, as long as the maximum value;

We can use the priority queue, how this is to come out of it? The number of consecutive face 3 (the first or free end position), reference numeral 1,2,3;

If we choose the 2nd hole, then 1,3 scrap it;

If you choose 1.3, then 2 can not be elected; (I represent do not want to analyze this kind of thing) (priority queue to help you achieve !!)

We default top of the heap is the maximum we are looking for, but we need to go through some processing;

The right and left ends position of each point is recorded l [i] = i-1; r [i] = i + 1;

N first thrown into a pit, then the top of the heap will be the largest value of that, we take out ans + = val (why, 1,3 how to do?)

It does not matter, because we can not choose option 1, 3, 1, 3, then we do not choose, and the value of 2 is taken out and then update the value of 2,

val [2] = val [1] + val [3] -val [2]; (ans need to update the value)

But we choose to avoid repetition, the vis [1] = vis [3] = 1; (not special access)

There is the equivalent of doing a group divided into three groups of three, we will post updates about the value you want to position 2 update (equivalent to become 0,2,4)

In fact, we solve the problem in groups of three connected end to end will be (if we want to choose 1,3, we will update this time is again 2. 0,2,4, pattern, they would not connect;)

(When selected from 1,3 and 0,4 have been compared)

Processing is complete;

When the pile is negative to exit on the line;

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
int a[maxn];
int n,k;
int l[maxn],r[maxn];
priority_queue<pair<int,int> > q;
ll ans;
int vis[maxn];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        //a[i].val=-a[i].val;
        q.push(make_pair(a[i],i));
        l[i]=i-1;
        r[i]=i+1;
    }
    r[0]=1;l[n+1]=n;
    while(k--)
    {
        while(vis[q.top().second]) q.pop();
        int x=q.top().first;
        int i=q.top().second;
        q.pop();
        if(x<0) break;
        ans+=(ll)x;
        a[i]=a[l[i]]+a[r[i]]-a[i];
        vis[l[i]]=1;vis[r[i]]=1;
        l[i]=l[l[i]];r[l[i]]=i;
        r[i]=r[r[i]];l[r[i]]=i;
        q.push(make_pair(a[i],i));
    }
    printf("%lld",ans);
    return 0;
}

 Look at these practices and code size, do you think this problem (it is hard to do) (escape ~);

 

Guess you like

Origin www.cnblogs.com/WHFF521/p/11528737.html