zoukankan      html  css  js  c++  java
  • 洛谷 P1040 加分二叉树

    P1040 加分二叉树

    树形dp,用记忆化搜索即可

    //树形dp P1040 
    //http://www.cnblogs.com/mhpp/p/6628528.html 
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int ans[31][31];//从l到r的结点构成的子树的最高加分
    int n;
    int root[31][31];//记录从l到r的结点构成的子树最高加分时的根结点
    int a[31];
    //显然,取最高得分就是取一个合适的根结点,使左子树的加分×右子树的加分+根的分数最大。  
    //因此,循环取l到r为根结点,然后对于每种根结点取法,分别递归求出左右子树最高加分,求出此情况最高得分,最终找到合适根结点。  
    int dfs(int l,int r)//从l到r的结点构成的子树的最高加分 
    {
    	if(l>r)	return 1;//空子树,返回1
    	if(l==r)//只有1个结点的子树,设定root后返回a[l]
    	{
    		//ans[l][r]=a[l];//可以去掉,因为不再用到这个值 
    		root[l][r]=l;//曾经忘记这一行,要注意 
    		return a[l];
    	}
    	if(ans[l][r])	return ans[l][r];//记忆化,已经算出答案,直接返回
    	int i,t;
    	for(i=l;i<=r;i++)
    	{
    		t=dfs(l,i-1)*dfs(i+1,r)+a[i];
    		if(t>ans[l][r])
    		{
    			root[l][r]=i;
    			ans[l][r]=t;
    		}
    	}
    	return ans[l][r];
    }
    void print(int l,int r)
    {
    	if(root[l][r])
    	{
    		printf("%d ",root[l][r]);
    		print(l,root[l][r]-1);
    		print(root[l][r]+1,r);
    	}
    }
    int main()
    {
    	int i;
    	scanf("%d",&n);
    	for(i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	dfs(1,n);
    	printf("%d
    ",ans[1][n]);
    	print(1,n);
    	return 0;
    } 
  • 相关阅读:
    移动终端app测试点总结
    Android测试环境搭建(win7)
    Jenkins知识地图
    Jenkins快速上手
    接口测试总结
    性能测试总结(三)--工具选型篇
    性能测试总结(二)---测试流程篇
    性能测试总结(一)---基础理论篇
    网友评论诺基亚和Android
    手撕伪鸡汤,人事部门经理给你的八个职场忠告
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8470448.html
Copyright © 2011-2022 走看看