zoukankan      html  css  js  c++  java
  • 洛谷P2015 二叉苹果树

    题面:

    有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

    这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

    我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

    2   5
      / 
      3   4
        /
        1
    

    现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

    给定需要保留的树枝数量,求出最多能留住多少苹果。

    输入输出格式

    输入格式:

    第1行2个数,NNQ(1<=Q<=N,1<N<=200)Q(1<=Q<= N,1<N<=200)

    N表示树的结点数,Q表示要保留的树枝数量。接下来N1N-1行描述树枝的信息。

    每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

    每根树枝上的苹果不超过30000个。

    输出格式:

    一个数,最多能留住的苹果的数量。

    输入输出样例

    输入样例

    5 2
    1 3 1
    1 4 10
    2 3 20
    3 5 20
    

    输出样例

    21
    

    分析:

    f[i][j]f[i][j] 表⽰以i节点为根,保留j个树枝最多留下
    多少个苹果。
    只给左⼉⼦:f[i][j]=f[lson[i]][j1]+vlson[i]f[i][j]=f[lson[i]][j-1]+vlson[i]
    只给右⼉⼦:f[i][j]=f[rson[i]][j1]+vrson[i]f[i][j]=f[rson[i]][j-1]+vrson[i]
    都分⼀点:f[i][j]=max(f[lson[i]][k]+f[rson[i]][jk2]+vlson[i],vrson[i]).0<=k<=j2f[i][j]=max(f[lson[i]][k]+f[rson[i]][j-k-2]+vlson[i],vrson[i]). 0<=k<=j-2.

    另种思路在代码中说明

    code:(搜索+dp)

    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,q;
    struct ben
    {
    	int to,last,val,dq;//to记录这条边的终点,last记录上一条边,dq记录边的起点,val记录边的权值
    }a[205];
    int f[205][205];
    int cnt=1;
    int head[205];//head[i]表示以i为起点的边的编号
    void add(int x,int y,int num)//连边函数
    {
    	a[cnt].to=y;
        a[cnt].last=head[x];
        a[cnt].dq=x;
        a[cnt].val=num;
        head[x]=cnt;
        cnt++;
    }
    void search(int dq,int father)
    {
    	for(int i=head[dq];i!=-1;i=a[i].last)
    	{
    		int b=a[i].to;//找到这条边的终点
    		if(b==father)continue;//不能为起点
    		f[b][1]=a[i].val;//初始化
    		search(b,dq);//搜索
    		for(int j=q;j>=1;j--)
    		{
    			for(int k=0;k<=j;k++)
    			{
    				if((j!=1&&j!=k)||dq==1)
    				{
    					f[dq][j]=fmax(f[dq][j],f[b][k]+f[dq][j-k]);//枚举中间点k,得出方程
    				}
    			}
    		}
    	}
    }
    int main()
    {
    	
    	scanf("%d%d",&n,&q);
    	for(int i=1;i<=n;i++)
    	{
    		head[i]=-1;
    	}//初始化
    	for(int i=1;i<n;i++)
    	{
    		int x,y,num;
    		scanf("%d%d%d",&x,&y,&num);
    		add(x,y,num);
    		add(y,x,num);//注意要连双向边
    	}
    	search(1,0);
    	printf("%d",f[1][q]);
    	return 0;
    }
    
  • 相关阅读:
    168. Excel Sheet Column Title
    171. Excel Sheet Column Number
    264. Ugly Number II java solutions
    152. Maximum Product Subarray java solutions
    309. Best Time to Buy and Sell Stock with Cooldown java solutions
    120. Triangle java solutions
    300. Longest Increasing Subsequence java solutions
    63. Unique Paths II java solutions
    221. Maximal Square java solutions
    279. Perfect Squares java solutions
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834334.html
Copyright © 2011-2022 走看看