• Codeforces Round #525 (Div. 2)后俩题


    E:https://codeforces.com/contest/1088/problem/E

    dp+贪心

    题目大意:选择一个k并且选择k个连通块,
    要求sigma a[i]/k最大,k尽量大,
    对于给定的一颗树,输出最大的分数,不用约分的形式。
    题目意思需要进一步解析,
    假定有一个最大的连通块,那么
    根据贪心的思想,肯定是选择这个连通块,但
    又要求k大,所以把所有大小为这个连通块的dp值都计数一遍,
    因为我们知道两个最大的连通块不可能有交集,
    如果有,肯定是交集部分就是最大值部分,其余的部分都是零,
    那么我们从下往上递归求解的过程中,其实也是一种贪心选取,
    在计数完当前位置的dp值后,把该位置置为无穷小防止后面再被选取。

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int M=3e5+5;
    const ll INF=1e18;
    ll ans,cnt,dp[M],a[M];
    vector<int>g[M];
    void dfs(int u,int f,int sign){
        dp[u]=a[u];
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i];
            if(v==f)
                continue;
            dfs(v,u,sign);
            dp[u]+=max(0ll,dp[v]);
        }
        if(sign==1){
            ans=max(ans,dp[u]);
        }
        else if(dp[u]==ans)
    
                cnt++,dp[u]=-INF;
    }
    int main(){
        int n;
        ans=-INF;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%I64d",&a[i]);
        for(int u,v, i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            g[u].pb(v);
            g[v].pb(u);
        }
        dfs(1,0,1);
        dfs(1,0,0);
        printf("%I64d %I64d",cnt*ans,cnt);
        return 0;
    }
    View Code

     F:https://codeforces.com/contest/1088/problem/F

    题意:给你n个点的权值ai,一棵树,定义dist(a,b)为这棵树上两点的距离,且除了唯一的一个权值最小的点,每个点都必有一个相邻点权值比其小,要你构造一颗新的树,

       规定每加一条边u<-->v,w就加au+av+log2( dist(u,v) )* min( au , av )。求出最小的w。
       给出的树仅代表他们之间的距离!!!

    分析:

       类似于MST的做法,考虑每次加入一个点i,贡献为ai+aj*(1+log2(距离))。最小化aj*(log2(距离))
       题目有给保证这棵树除了最小值节点,其他节点均存在一条邻边,使得边的另一点的值比它小
       所以以最小的点为根向下dfs,维护每个点2^k级祖先,存在这样一个性质:每个点的所属边必然只可能连向它的某个2^k级祖先或者根节点。
       因为要在这个点log2(距离)相同的情况下要尽量小

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int M=5e5+5;
    const ll INF=1e18;
    vector<int>g[M];
    int root,a[M],dp[21][M];
    ll ans;
    void dfs(int u,int f){
        dp[0][u]=f;
        for(int i=1;i<20;i++){
            if(dp[i-1][u]==-1)
                break;
            dp[i][u]=dp[i-1][dp[i-1][u]];
        }
        ll deep;
        ll minn=INF;
        for(deep=0;deep<20&&dp[deep][u]!=-1;deep++){
            minn=min(minn,(deep+1)*a[dp[deep][u]]+a[u]);
        }
        minn=min(minn,(deep+1)*a[root]+a[u]);
        if(f!=-1)
            ans+=minn;
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i];
            if(v!=f)
                dfs(v,u);
        }
    }
    int main(){
        int n;
        root=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(a[i]<a[root])
                root=i;
        }
    
        for(int u,v,i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            g[u].pb(v);
            g[v].pb(u);
        }
        memset(dp,-1,sizeof(dp));
        dfs(root,-1);
        printf("%I64d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    将1、2、3、……、n这n个连续自然数分成g组,使每组的和相等。g组中个数最多的一组有几个?
    磁带机、驱动器、磁带库、机械手之间的区别
    Mysql基础命令
    pip 加速下载
    NBU命令之 nbftconfig :配置与光纤传输 (FT) 服务器和 SAN 客户端相关的属性
    IEDriverServer.exe驱动问题汇总
    系统集成项目管理工程师考试2020介绍
    LTO1,LTO2,LTO3,LTO4,LTO5 LTO6 磁带读写速度和兼容性及LTO6主要参数
    Mysql 备份方式 MySQL Agent & MySQL Enterprise Backup & Percona XtraBackup
    Netbackuk命令之bpclntcmd
  • 原文地址:https://www.cnblogs.com/starve/p/11804957.html
Copyright © 2020-2023  润新知