uva10304 - Optimal Binary Search Tre(区间动态规划)

还是建立不起来自己的动归意识啊。。。。

输入的数据是有序递增的,所以省去了排序的步骤。

思路:对每个区间选出一个点当作根节点。。。而区间上除了根节点左右最优解要多加一个高度,

状态:dp[i][j]表示a[i]到a[j]所构成的二叉树的最小代价。

状态转移:dp[i][j] =  min(dp[i][k-1]+dp[k+1][j]+sum[j]-sum[i-1]-a[k]); {i<k<j;}

代码如下:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 300
#define INF 0x7fffffff
int n, a[M], dp[M][M], sum[M];
int main ()
{
    sum[0] = 0;
    while(~scanf("%d",&n))
    {
        for(int i = 1; i <= n; i++) { scanf("%d",&a[i]); sum[i] = sum[i-1]+a[i]; dp[i][i] = 0; }

        for(int len = 1; len < n; len++)
            for(int i = 1, j = i+len; j <= n+1; i++,j++)
            {
                dp[i][j] = INF;
                dp[i][j] = min(dp[i][j],dp[i+1][j]+sum[j]-sum[i-1]-a[i]);
                dp[i][j] = min(dp[i][j],dp[i][j-1]+sum[j]-sum[i-1]-a[j]);
                for(int k = i+1; k <= j-1; k++)
                {
                    dp[i][j] = min(dp[i][j],dp[i][k-1]+dp[k+1][j]+sum[j]-sum[i-1]-a[k]);
                }
            }
        printf("%d\n",dp[1][n]);
    }
    return 0;
}

你可能感兴趣的:(uva10304 - Optimal Binary Search Tre(区间动态规划))