• 洛谷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;
    }
    
  • 相关阅读:
    pytest框架运用
    unitTest学习
    发送邮件
    python 连接远程服务器,修改时间
    Redis基础
    django 知识点扩展
    ACM 题目 1487: [蓝桥杯][算法提高VIP]不同单词个数统计
    Leetcode 面试题 08.01. 三步问题
    Leetocode 198. 打家劫舍
    Leetcode 121. 买卖股票的最佳时机
  • 原文地址:https://www.cnblogs.com/ShineEternal/p/10834334.html
Copyright © 2020-2023  润新知