概述
https://www.luogu.com.cn/problem/P1273
思路:
dp[i][j]:以i为根的子树服务j个用户的最大收益。
答案遍历到dp[i][j]>=0的时候更新最值
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e3+100;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL val[maxn],out[maxn],siz[maxn];
struct Edge{
LL to,cost;
};
vector<Edge>g[maxn];
LL dp[maxn][maxn];
void dfs(LL u,LL fa){
siz[u]=1;
dp[u][0]=0;
if(out[u]==0) dp[u][1]=val[u];///叶子的价值初始化
for(LL i=0;i<g[u].size();i++){
LL v=g[u][i].to;LL cost=g[u][i].cost;
if(v==fa) continue;
dfs(v,u);
siz[u]+=siz[v];
for(LL j=siz[u];j>=1;j--){
for(LL k=1;k<=j;k++){
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-cost);
}
}
}
}
int main(void){
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,m;cin>>n>>m;
for(LL i=1;i<=n-m;i++){
LL k;cin>>k;
for(LL j=1;j<=k;j++){
LL v,cost;cin>>v>>cost;
g[i].push_back({v,cost});out[i]++;
g[v].push_back({i,cost});
}
}
for(LL i=1;i<=n;i++){
if(out[i]==0){
cin>>val[i];
}
}
memset(dp,-0x3f,sizeof(dp));
dfs(1,-1);
LL ans=0;
for(LL j=1;j<=n;j++){
if(dp[1][j]>=0){
ans=max(ans,j);
}
}
cout<<ans<<"n";
return 0;
}
最后
以上就是魁梧刺猬为你收集整理的P1273 有线电视网(树形dp)的全部内容,希望文章能够帮你解决P1273 有线电视网(树形dp)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复