zoukankan      html  css  js  c++  java
  • 2019-2020 XX Open Cup, Grand Prix of Korea

    2019-2020 XX Open Cup, Grand Prix of Korea

    J. Park life

    题意

    给你S个节点,E条边,每条边有一个美丽值且每条边能覆盖[l,r)的点,询问 (kin [1,n]) 每个点最多被覆盖k次的总美丽值的最大值

    题解

    把每个序列加上一个'源点'按照左端点小,右端点大排序,,则可以得到一个树的先序序列,从而可以构建出一棵树。(不加源点会出现森林)

    可以容易想到一个树形dp,第i个节点,选择i和不选择i,(dp[x][k]=max(sum dp[son][k],dp[son][k-1]+val[x]))(但是会超时需要优化

    因为k一定是在k-1的基础上额外选择节点,所以答案一定是递增的,可以用小根堆维护子树的信息。

    设节点i的答案集合为(dp[i]),代表 i 子树中,所有顶点最多被''覆盖''一次的答案集合:

    对于叶子节点肯定只有val这一个权值(dp[i]=val),对于祖宗节点,答案集合为所有儿子集合的组合+val。因为要求答案递增,所以一定是从小到大或从大到小顺序的组合。

    题意也可以这么理解,选过的边不能重复选,(ans_k)为不间断选k次的最大值,则上述的dp[0]从大到小分别是第i次每个点最多被覆盖一次的答案,所以题目答案(ans_k=sum_{iin son[0]} dp[i])

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 3e5+7;
    int n,val[N];
     
    struct node
    {
        int l,r,pos;
     
    }a[N];
     
    vector <int> f[N];
    priority_queue <long long >dp[N];
    bool cmp(node x,node y)
    {
        if(x.l==y.l)
            return x.r>y.r;
        return x.l<y.l;
    }
     
    struct compare
    {
        bool operator ()(node x,node y)
        {
            if(x.l==y.l)
                return x.r>y.r;
            return x.l<y.l;
        }
    };
     
    void get_tree()
    {
        stack <node>s;
        for(int i=n;i>=0;i--)
        {
            while(!s.empty()&&(a[i].r>=s.top().r))
            {
                f[a[i].pos].push_back(s.top().pos);
                s.pop();
            }
            s.push(a[i]);
        }
        
    }
     
    void dfs(int x)
    {
    
        for(auto i:f[x])
        {
            dfs(i);
            if(dp[i].size()>dp[x].size())
            {
                swap(dp[x],dp[i]);//启发式合并
            }
            vector <long long > temp;
            while(!dp[i].empty()) //答案集合的顺序组合
            {
                temp.push_back(dp[i].top()+dp[x].top());
                dp[i].pop();
                dp[x].pop();
            }
            for(auto j:temp)
            {
                dp[x].push(j);
            }
        }
        dp[x].push(val[x]);//加上val
    }
    void print()
    {
        for(int i=0;i<=n;i++)
        {
            printf("i:%d
    ",i);
            for(auto j:f[i])
            {
                printf("%d
    ",j);
            }
            printf("
    ");
        }
    }
    int main()
    {
        scanf("%d",&n);
        a[0].l=0,a[0].r=1e6+5;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d",&a[i].l,&a[i].r,&val[i]);
            a[i].r--;
            a[i].pos=i;
        }
        sort(a,a+n+1,cmp);
        get_tree();
     
        dfs(0);
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            if(!dp[0].empty())
            {
                ans+=dp[0].top();//每次答案累加
                dp[0].pop();
            }
            printf("%lld ",ans);
        }
        return 0;
    }
     
    
    /*
    6
    1 2 10
    2 3 10
    1 3 21
    3 4 10
    4 5 10
    3 5 19
     
    4
    1 5 1
    2 5 1
    3 5 1
    4 5 1
     
    */
    
  • 相关阅读:
    Java程序:从命令行接收多个数字,求和并输出结果
    大道至简读后感
    大道至简第一章读后感Java伪代码
    Creating a SharePoint BCS .NET Connectivity Assembly to Crawl RSS Data in Visual Studio 2010
    声明式验证超时问题
    Error message when you try to modify or to delete an alternate access mapping in Windows SharePoint Services 3.0: "An update conflict has occurred, and you must re-try this action"
    Upgrading or Redeploying SharePoint 2010 Workflows
    Upgrade custom workflow in SharePoint
    SharePoint 2013中Office Web Apps的一次排错
    How to upgrade workflow assembly in MOSS 2007
  • 原文地址:https://www.cnblogs.com/cherrypill/p/13978882.html
Copyright © 2011-2022 走看看