zoukankan      html  css  js  c++  java
  • caioj 1106 树形动态规划(TreeDP)1:加分二叉树

    解这道题的前提是非常熟悉中序遍历的方式
    我就是因为不熟悉而没有做出来
    中序遍历是5 7 1 2 10的话,如果1是根节点
    那么5 7 1就是1的左子树,2, 10就是右子树
    这就有点中链式dp的味道了,实际解法也是中链式dp的解法
    设f[i][j]为中序遍历从i到j的最大价值
    f[l][r] = f[l][mid-1] * f[mid+1][r] + d[mid]
    从小规模推到大规模
    dp过程中记录根节点以求前序遍历。

    #include<cstdio>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    const int MAXN = 30;
    int d[MAXN], f[MAXN][MAXN], root[MAXN][MAXN], n;
    
    void print(int l, int r)
    {
    	if(l <= r)
    	{
    		printf("%d ", root[l][r]);
    		print(l, root[l][r] - 1);
    		print(root[l][r] + 1, r);
    	}
    }
    
    int main()
    {
    	scanf("%d", &n);
    	REP(i, 0, n + 1)
    		REP(j, 0, n + 1)
    			f[i][j] = 1;
    	REP(i, 1, n + 1) 
    	{
    		scanf("%d", &d[i]);
    		f[i][i] = d[i];
    		root[i][i] = i;
    	}
    	
    	REP(k, 2, n + 1)
    		for(int l = 1; l + k - 1 <= n; l++)
    		{
    			int r = l + k - 1;
    			REP(mid, l, r + 1)
    				if(f[l][r] < f[l][mid-1] * f[mid+1][r] + d[mid])
    				{
    					f[l][r] = f[l][mid-1] * f[mid+1][r] + d[mid];
    					root[l][r] = mid;
    				}
    		}
    	
    	printf("%d
    ", f[1][n]);
    	print(1, n);
    	
    	return 0;
    }
  • 相关阅读:
    257. Binary Tree Paths
    poj2406 kmp
    hust1010 kmp
    hdu1358 kmp的next数组
    hdu3746 kmp求循环节
    hdu1686字符串kmp
    hdu2087kmp
    hdu1711kmp
    poj3067树状数组求逆序数
    poj1159二维树状数组
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819399.html
Copyright © 2011-2022 走看看