C小加

厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Ural 1018 Binary Apple Tree 解题报告

Posted on 2011-11-23 14:56 C小加 阅读(1334) 评论(0)  编辑 收藏 引用 所属分类: 解题报告
题意:一棵二叉苹果树,每个树枝上都有苹果,求剪枝后剩下Q根树枝的时候的最大苹果数量。(剪枝的时候不能连根拔起)
思路:TreeDP。先由题给出的关系建立一棵二叉树,把边上的苹果移动到子结点,然后对树进行自底而上的DP,状态转移方程式为:f[root][j]=max(f[root.lc][i]+f[root][j-1-i])+val[root];意思就是说当根root要保留j个点=root的左孩子保留i个点的最大苹果数+root的右孩子保留j-1-i个点的最大苹果数+root点的苹果数。

#include<iostream>
#include
<cstdio>
#include
<cstring>
using namespace std;
const int MAXN=103;
typedef 
struct
{
    
int lc,rc;
    
int val;
}Node;
Node tree[MAXN];
int m,n;
int arr[MAXN][MAXN];
int f[MAXN][MAXN];
int vis[MAXN];
void Create(int root)
{
    vis[root]
=1;
    
for(int i=1;i<=m;i++)
    {
        
if(!vis[i]&&arr[root][i])
        {
            
if(!tree[root].lc)
            tree[root].lc
=i;
            
else tree[root].rc=i;
            tree[i].val
=arr[root][i];
            Create(i);
        }
    }
}
int TreeDP(int root,int e)
{
    
if(!root||!e)return 0;
    
if(f[root][e])retu rn f[root][e];
    
int maxx=0;
    
int l,r;
    
for(int i=0;i<e;i++)
    {
        l
=TreeDP(tree[root].lc,i);
        r
=TreeDP(tree[root].rc,e-i-1);
        maxx
=max(l+r,maxx);
    }
    f[root][e]
=maxx+tree[root].val;
    
return f[root][e];
}
int main()
{
    memset(arr,
0,sizeof(arr));
    memset(vis,
0,sizeof(vis));
    memset(tree,
0,sizeof(tree));

    scanf(
"%d %d",&m,&n);
    
int l,f,v;
    
for(int i=1;i<m;i++)
    {
        scanf(
"%d %d %d",&l,&f,&v);
        arr[l][f]
=arr[f][l]=v;
    }
    Create(
1);
    printf(
"%d\n",TreeDP(1,++n));
    
return 0;
}



只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理