• hdu4003(树形dp)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003

    题意:给定一棵n个节点的树,遍历每条数边都需要费用cost,现在给定k个机器人,要求用这个k个机器人遍历整棵树,使得经过的费用和最小,n<=10000.

    分析:dp[u][j]表示有j个机器人不回来的最小值,dp[u][0]表示有一个机器人回来的最小值,即没有一个机器停留在那颗子树上。至于为甚么只考虑一个机器人回来的原因是同时派多个机器人下去,如果回来的人越多,走重复路线会越多,耗费越多。

    这里的树形dp和以往有点不同,原本树形dp对于每个根节点u的儿子v相当于分组背包里的一组,对于每组里的物品(v的儿子)至多取一个进行dp,这里因为要遍历完所有边,所以对于每组的物品必须取一个。

     总而言之,假设根节点u有x个子节点,dp[u][j]=min(dp[v1][num1]+dp[v2][num2]+...+dp[vx][numx])

    如何分配numk(0<=numk<=j)让num1+num2+...+numx=j使得dp[u][j]值最小。这里对于每个子节点numk枚举0~j枚举一遍就好。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define N 10010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    using namespace std;
    struct edge
    {
        int v,w,next;
        edge(){}
        edge(int v,int w,int next):v(v),w(w),next(next){}
    }e[2*N];
    int head[N],tot,n,m,s;
    int dp[N][15];
    void addedge(int u,int v,int w)
    {
        e[tot]=edge(v,w,head[u]);
        head[u]=tot++;
    }
    void dfs(int u,int fa)
    {
    
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].v,w=e[i].w;
            if(v==fa)continue;
            dfs(v,u);
            for(int j=m;j>=1;j--)
            {
                dp[u][j]+=dp[v][0]+2*w;//派一个人下去遍历完后再回来,保证选了一个
                for(int k=1;k<=j;k++)//枚举派多个下去,选出最优值
                    dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]+w*k);
            }
            dp[u][0]+=dp[v][0]+2*w;
        }
    }
    int main()
    {
        int u,v,w,sum;
        while(scanf("%d%d%d",&n,&s,&m)>0)
        {
            FILL(head,-1);FILL(dp,0);tot=0;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
            dfs(s,-1);
            printf("%d
    ",dp[s][m]);
        }
    }
    View Code
  • 相关阅读:
    appium 方法整理
    appium_获取元素状态
    Locust性能测试_参数关联
    Locust性能测试-参数化批量注册
    pytest_命令行传参
    pytest_函数传参和firture传参数request
    pytest_用例a失败,跳过测试用例b和c并标记失败xfail
    pytest_skip跳过用例
    pytest_使用自定义标记mark
    算法:迷宫问题
  • 原文地址:https://www.cnblogs.com/lienus/p/4207417.html
Copyright © 2020-2023  润新知