zoukankan      html  css  js  c++  java
  • P273.有线电视网(树上背包)

    题意:

    给出一棵树。

    每个叶子有点权,每条边有边权。

    问你最多选多少叶子,使得总边权小于等于总点权。

    题解:

    树上背包。

    定义状态(f(i,j,k))表示子树(i)内选取(j)个叶子仅考虑(i)的前(k)个儿子的最优答案。

    这里注意状态的转移的一些细节。

    //f(i,j,k)表示在子树i内选择j个用户的最大收益(仅考虑前k个儿子)
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3005;
    int f[maxn][maxn][2];
    int sz[maxn];
    vector<pair<int,int> > g[maxn];
    int a[maxn];
    int e[maxn];
    int n,m;
    void dfs (int x,int pre,int lst) {
    	int k=1;
    	sz[x]=1;
    	if (g[x].size())
    		f[x][0][0]=-lst+a[x];
    	else
    		f[x][1][0]=-lst+a[x];
    	for (pair<int,int> it:g[x]) {
    		int y=it.first;
    		int w=it.second;
    		if (y==pre) continue;
    		dfs(y,x,w);
    		for (int i=0;i<=sz[x];i++) {
    			for (int j=0;j<=sz[y];j++) {
    				f[x][i+j][k]=max(f[x][i+j][k],f[x][i][k^1]+f[y][j][e[y]]);
    			}
    		}
    		for (int i=0;i<=sz[x];i++) f[x][i][k]=max(f[x][i][k],f[x][i][k^1]);
    		sz[x]+=sz[y];
    		k^=1;
    	}
    	e[x]=(k^1);
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	for (int i=0;i<=n;i++) for (int j=0;j<=n;j++) for (int k=0;k<2;k++) f[i][j][k]=-1e9;
    	for (int i=1;i<=n-m;i++) {
    		int k;
    		scanf("%d",&k);
    		for (int j=1;j<=k;j++) {
    			int x,y;
    			scanf("%d%d",&x,&y);
    			g[i].push_back(make_pair(x,y));
    		}
    	}
    	for (int i=n-m+1;i<=n;i++) scanf("%d",a+i);
    	dfs(1,0,0);
    	int ans=0;
    	for (int j=0;j<=m;j++) if (f[1][j][e[1]]>=0) ans=j;
    	printf("%lld
    ",ans);
    }
    
    
  • 相关阅读:
    struts 提交问题
    struts spring整合出错
    hibernate.cfg.xml
    myeclipse copy问题
    myeclipse copy时出的问题
    mysql sql 语句
    Spring_Hibernate
    WebView
    Notification
    Handler(消息机制)
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14632719.html
Copyright © 2011-2022 走看看