|CCF20161204壓縮編碼【區間DP】

思路

與傳統的哈夫曼編碼不同,本題的編碼只能是相鄰的進行構造。我們發現每一個字母的編碼的長度相當於在一顆編碼樹中的深度。我們回想一下,石子合併,在石子合併過程中,每個數被合併的次數就相當於一個字母的編碼長度在一顆編碼樹中的深度,而每堆石子的數量就相當於字母出現的頻率數,因此,這道題的本質就是一道裸的區間DP。

AC代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3 + 5;
int a[maxn];
int sum[maxn];
int dp[maxn][maxn];
int main(void) {
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        sum[i] += sum[i-1]+a[i];
    }
    for(int len = 2; len <= n; len++){ //枚舉區間長度
        for(int i = 1; i+len-1<=n; i++){
            int j = i+len-1;        //i是區間起點,j是區間終點
            dp[i][j] = 0x3f3f3f3f;
            for(int k = i; k <= j; k++){
                dp[i][j] = min(dp[i][j],dp[i][k-1]+dp[k][j]+sum[j]-sum[i-1]);
            }
        }
    }
    cout<<dp[1][n]<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章