洛谷 P1273 有线电视网

2016-05-31 13:25:45

题目链接: 洛谷 P1273 有线电视网

题目大意:

  在一棵给定的带权树上取尽量多的叶子节点,使得sigma(val[选择的叶子节点])-sigma(cost[经过的边])>=0

解法:

  树状DP 背包DP

  DP[i][j]表示i号节点为根的子树中选择了j个叶子节点所得到的最大利润

  转移方程

    DP[i][j]=max(DP[i][j],DP[i][j-k]+DP[son][k]-cost[son][i]);

需要注意的地方

  写初始值的时候要注意除了DP[i][0]=0,全部都是-inf

 1 //有线电视网 (洛谷 No.1273)
 2 //树状DP 背包DP
 3 #include<stdio.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=3010;
 7 int DP[maxn][maxn];
 8 struct edge
 9 {
10     int to;
11     int cost;
12     int next;
13     edge(){}
14     edge(int to,int cost,int next):to(to),cost(cost),next(next){}
15 };
16 edge n[maxn];
17 int head[maxn];
18 int cnt;
19 void insert(int x,int y,int z)
20 {
21     n[++cnt]=edge(y,z,head[x]);
22     head[x]=cnt;
23     return ;
24 }
25 int N,M;
26 int val[maxn];
27 int DFS(int x)
28 {
29     if(x>N-M)
30     {
31         DP[x][1]=val[x];
32         return 1;
33     }
34     int sum=0;
35     for(int i=head[x];i;i=n[i].next)
36     {
37         int size=DFS(n[i].to);
38         sum+=size;
39         for(int j=sum;j>=0;j--)
40         {
41             for(int k=1;k<=size;k++)
42             {
43                 DP[x][j]=max(DP[x][j],DP[x][j-k]+DP[n[i].to][k]-n[i].cost);
44             }
45         }
46     }
47     return sum;
48 }
49 int main()
50 {
51     scanf("%d %d",&N,&M);
52     for(int i=0;i<maxn;i++)
53     {
54         fill(DP[i],DP[i]+maxn,-1000000);
55     }
56     for(int i=1;i<=N;i++)DP[i][0]=0;
57     for(int i=1;i<=N-M;i++)
58     {
59         int x;
60         scanf("%d",&x);
61         for(int j=1;j<=x;j++)
62         {
63             int to,val;
64             scanf("%d %d",&to,&val);
65             insert(i,to,val);
66         }
67     }
68     for(int i=N-M+1;i<=N;i++)
69     {
70         scanf("%d",&val[i]);
71     }
72     DFS(1);
73     for(int i=M;i>=0;i--)
74     {
75         if(DP[1][i]>=0)
76         {
77             printf("%d",i);
78             return 0;
79         }
80     }
81     return 0;
82 }
时间: 2024-08-29 14:23:13

洛谷 P1273 有线电视网的相关文章

洛谷 P1273 有线电视网(dp)

/* 想了半天没想出状态 自己还是太弱了 QAQ 题目问的是最多供给多少户 一般想法是把这个值定义为状态量 没想出来QAQ....看了看题解的状态 很机智.... f[i][j]表示i的子树 选了j个叶子的最大收益 这样 不亏本就是收益>=0 转移的话 先搜一下这个子树有几个叶子 然后枚举儿子 枚举当前儿子分几个叶子 这里的枚举顺序有套路 从大到小枚举i分几个 从小到大枚举j分几个 这样可以避免 重复选择 注意初始化 */ #include<iostream> #include<c

洛谷1273 有线电视网

本题地址:http://www.luogu.org/problem/show?pid=1273 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和.     现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供

luogu P1273 有线电视网

题目链接 luogu P1273 有线电视网 题解 树形背包 dp[i][j]表示在以i为根的子树中,满足j个客户的需求所能获得的最大收益 代码 #include<cstdio> #include<algorithm> #include<cstring> const int maxn = 3007; //using namespace std; inline int read() { int x = 0,f = 1; char c = getchar(); while(

洛谷 P1273 【有线电视网】

题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多. 输入 输入文件的

Luogu P1273 有线电视网(树形dp+背包)

题面 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多. 输入输出格

[P1273]有线电视网

Link: P1273 传送门 Solution: 比较裸的树形$dp$ 令$dp[i][j]$表示以$i$为根的子树中选$j$个叶子的最小代价 最后找到使得$dp[1][k]\ge 0$的最大$k$即可 Code: #include <bits/stdc++.h> using namespace std; const int MAXN=3005; struct edge{int nxt,to;}e[MAXN<<2]; int n,m,x,y,w[MAXN],sz[MAXN],dp

[P1273] 有线电视网 (树形DP+分组背包)

题意:给出一棵树,有边权,只有叶子节点有点权,求一个合法方案(选择走到哪几个叶子节点,且路径上的权值和 <= 要走到的叶子节点的点权和),使得选择的叶子节点数量尽量的多: 解法:树形DP+分组背包: 1.树形DP:这是一棵树,所以叫树形DP: 2.分组背包:在这里主要是运用到了它的思想:我们可以设 f[i][j],表示 i节点选择了 j个叶子节点的费用最大值:假设现在在 x节点,它的下面有 n个叶子节点(不是它的儿子),那么我们就要处理出它选 1,2,3,……,n 个叶子节点的情况,但是由于这是

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可