24h購物| | PChome| 登入
2012-06-30 08:07:51| 人氣408| 回應0 | 上一篇 | 下一篇

[PTC] 201206B Tree Balance 動態規劃

推薦 0 收藏 0 轉貼0 訂閱站台

Problem B
Tree Balance
Input le: testdata.in
Time limit: 1 seconds
Problem Description
We have n nodes, each of them has its node number i and weight wi for the
i-th node. We want to construct a binary tree by these nodes such that the
sequence of node numbers of in-order traversal is from 1 to n. Figure 1 is
a possible tree when n is 5. The sequence of the node number of inorder
traversal of the tree is 1, 2, 3, 4, 5.
2
1 4
3 5
Figure 1: Example of possible tree when n is 5. Note that the weight of each
node is not shown here.
There are many trees meet the requirement. De ne S(T) as the sum of
the weights of all nodes in the tree T, V (T) as the skewing value of the tree
T, where V (T) = (S(TL) - S(TR))2 + V (TL) + V (TR). For an empty tree E
we de ne V (E) = S(E) = 0. Can you tell us the minimum skewing value of
these trees?

Technical Speci cation

 1  N  100
0  wi  1000

Input Format

There are multiple test cases in the input. Each test case starts with a line
containing the number of nodes N. Then followed with a line, containing the
weights of the N nodes, separated by a white space.

Output Format
For each test cases, output the minimum skewing value of the N nodes in a
line.

Sample Input
1
4
4
1 2 3 4

Sample Output

0
2

題目意思 : 給一個中搜走訪的結果, 詢問其中一個根的 V(root) 最小

由於 V(T) 會加上左右子樹總合差的平方, 又因為是中序搜尋的結果,
因此可以想成左邊當作左子樹, 右邊當作右子樹, 就會得到下面的遞迴式,
窮舉要當成樹的根的地方, 寫遞迴比較好寫, 記住答案可能會超過 int 的範圍

#include <stdio.h>
#include <string.h>
long long dp[101][101] = {}, w[101] = {};
long long dfs(int i, int j) {
    if(dp[i][j] != -1)
        return dp[i][j];
    long long min = 0xfffffffffffffffLL, tmp;
    int k;
    for(k = i; k <= j; k++) {
        tmp = dfs(i, k-1) + dfs(k+1, j) + (w[j]-w[k]-w[k-1]+w[i-1])*(w[j]-w[k]-w[k-1]+w[i-1]);
        if(tmp < min)
            min = tmp;
    }
    dp[i][j] = min;
    return dp[i][j];
}
int main() {
    int n, i;
    while(scanf("%d", &n) == 1) {
        memset(dp, -1, sizeof(dp));
        for(i = 1; i <= n; i++) {
            scanf("%lld", &w[i]);
            w[i] += w[i-1];
            dp[i][i] = 0;
            dp[i][i-1] = 0;
        }
        printf("%lld\n", dfs(1, n));
    }
    return 0;
}

台長: Morris
人氣(408) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: 其他題目 |
此分類下一篇:[趣題] dolls.rar 解開所有的壓縮檔吧!
此分類上一篇:[PTC] 201206E Circular Codes 最小表示法

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文