1. 程式人生 > >【洛谷P1273】有線電視網

【洛谷P1273】有線電視網

define ans names www. pri 電視 while tex text

有線電視網

題目鏈接

樹形DP,分組背包

dp[u][i][j]表示以u為根的子樹,前i個子樹中選j個用戶的最大收益.

dp[u][size[u]][0]=0;

dp[u][i][j]=max(dp[u][i][j],dp[u][i-1][j-k]+dp[v][size[v]][k]-w[u][v]);

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 3010
int n,m,dp[N][N],val[N];
struct NODE{
    
int to,w,next; } e[N]; int Head[N],num; inline void add(int x,int y,int w){ e[++num].to=y; e[num].w=w; e[num].next=Head[x]; Head[x]=num; } inline int read(){ int x=0; char c=getchar(); while(c<0||c>9) c=getchar(); while(0<=c&&c<=9) { x=(x<<3
)+(x<<1)+c-0; c=getchar(); } return x; } int dfs(int u){ dp[u][0]=0; if(u>n-m){ dp[u][1]=val[u]; return 1; } int sum=0; for(int i=Head[u];i;i=e[i].next){ int v=e[i].to; int sz=dfs(v); for(int j=sum;j>=0;j--) for(int k=1
;k<=sz;k++) dp[u][j+k]=max(dp[u][j+k],dp[u][j]+dp[v][k]-e[i].w); sum+=sz; } return sum+1; } int main() { memset(dp,~0x3f,sizeof(dp)); n=read(); m=read(); int snum,y,w; for(int i=1;i<=n-m;i++){ snum=read(); while(snum--){ y=read(); w=read(); add(i,y,w); } } for(int i=n-m+1;i<=n;i++) val[i]=read(); dfs(1); int ans=0; for(ans=m;ans>=1;ans--) if(dp[1][ans]>=0) break; printf("%d\n",ans); return 0; }

【洛谷P1273】有線電視網