zoukankan      html  css  js  c++  java
  • Evanyou Blog 彩带

      题目传送门

      分析:首先看小范围的数据,很容易可以想到用DP,方程为f[i][j]=max(f[i-1][j],f[i-2][j-1]+a[i]),f[i][j]表示到第i个坑种了j棵树的最大收益。但是很显然不能过全部数据(亲测只有五十分)。正解以该要用优先队列,将所有的数据丢进一个大根堆中维护,然后每次取出一个最大的,然后把左右两边的坑合并,将其值变为a[l[i]]+a[r[i]]-a[i]再丢进堆中维护,因为容易证明,对于相邻的三个坑,要么选择a[i],要么选择a[i-1]和a[i+1]两个。实在不理解就看代码吧。

      Code:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<iomanip>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int N=5e5+7;
    ll n,m,a[N],l[N],r[N];
    ll ans;bool vis[N];
    struct Tree
    {
        ll val;int id;    
    }t[N];
    priority_queue<Tree>team;
    bool operator < (const Tree &a,const Tree &b)
    {
        return a.val<b.val;
    }
    inline ll read()
    {
        char ch=getchar();ll num=0;bool flag=false;
        while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
        while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
        return flag?-num:num;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
            t[i].id=i;
            t[i].val=a[i];
            l[i]=i-1;
            r[i]=i+1;
            team.push(t[i]);
        }
        ll num=n;
        while(m--)
        {
            Tree x=team.top();
            team.pop();
            while(!team.empty()&&vis[x.id])
            {
                x=team.top();
                team.pop();
            }
            if(x.val<0)break;
            ans+=x.val;num++;
            vis[x.id]=true;
            vis[l[x.id]]=true;
            vis[r[x.id]]=true;
            int ls=l[x.id],rs=r[x.id];
            l[num]=l[ls];r[num]=r[rs];
            r[l[num]]=num;l[r[num]]=num;
            a[num]=a[ls]+a[rs]-a[x.id];
            team.push((Tree){a[num],num});
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    mysql小数和类型转换函数
    concat()用法
    sql修改表名字段名
    having函数,case when与order by
    volatile实现原理与应用
    synchronized的实现原理与应用
    java8策略模式
    centos7快速升级gcc
    一个用户从发起请求到接收到响应,中间经过哪些服务,每个服务做什么事情
    Java注解
  • 原文地址:https://www.cnblogs.com/cytus/p/8612332.html
Copyright © 2011-2022 走看看