首页 > 其他 > 详细

树形DP——P1273 有线电视网

时间:2021-03-15 22:51:31      阅读:28      评论:0      收藏:0      [点我收藏+]

树形DP——P1273 有线电视网

这道题和之前的那个一样是分组背包。我发现分组背包的套路都是这样省的:

技术分享图片

 

一般这个题目的dp[ i ][ j ]的意思是以 i 这个节点为根的子树,容纳 j  个***东西所获得的最大价值。

上面的temp是u这个节点的下面的最大子树返回的 那个***的东西的数量(就是 j 那个位置代表的东西), 然后 sum 这个值是以 u 这个节点为根节点的子树返回的的那个***的值。然后基本的思路就是和分组背包一样,把每个子树看成一组,然后通过子树的组来更新大的组。

然后注意这里的边权,如果要加入以 j 为根节点的子树的***的东西,那么必须要花费从 u -> v 这个的边权的花费。

 

至于初始化的话基本就是初始化叶子节点的值。

 

code

#include<iostream>
#include<string>
#include<cstring> 
using namespace std;
const int MAXN = 3e3+10;
int cost[MAXN];
int dp[MAXN][MAXN];
struct Edge{
    int v, next, w;
}edge[MAXN];
int head[MAXN];
int cnt;


void addEdge(int u, int v, int w){
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    edge[cnt].w = w;
    head[u] = cnt++;
    return;
}

void ini(int n, int m)
{
    for(int i = 1; i <= n; i++)
        head[i] = -1;
    cnt = 0;
//    for(int i = 1; i <= n; i++)
//    {
//        for(int z = 1; z <= m; z++)
//            dp[i][z] = -1;
//    }
    memset(dp, ~0x3f, sizeof(dp));
    for(int i = 1; i <= n; i++)
        dp[i][0] = 0;
    return;
}


int dfs(int u)
{
    int sum;
    if(cost[u])
        sum = 1;
    else 
        sum = 0;
    int temp;
    for(int i = head[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].v;
        temp = dfs(v); sum +=temp;
        for(int z = sum; z >= 1; z--)
        {
            for(int j = 1; j <= z&& j <= temp; j++)
            {
                dp[u][z] = max(dp[u][z], dp[u][z-j]+dp[v][j]-edge[i].w);
            }
        }
    }
    return sum;
}

int main()
{
    int n, m;
    cin >> n >> m;
    ini(n, m);
    int num1 = n-m; 
    for(int i = 1; i <= num1; i++)
    {
        int num2, v, w;
        cin >> num2;
        for(int z = 1; z <= num2; z++)
        {
            cin >> v >> w;
            addEdge(i, v, w);
        }
    }
    for(int i = n-m+1; i <= n; i++)
    {
        cin >> cost[i];
        dp[i][1] = cost[i];
    }
    dfs(1);
    int ans = 0;
    for(int i = 1; i <= m; i++)
    {
        if(dp[1][i] >= 0) ans = i;
    }
    cout << ans;
    return 0;
}

 

树形DP——P1273 有线电视网

原文:https://www.cnblogs.com/hyb-bbfss/p/14540059.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!