數字三角形--動態規劃

問題的提出:

  • 在數字三角形中尋找一條從頂部到底邊的路徑,
  • 使得路徑上所通過的數字之和最大。
    如:
    {2},
    {6,9},
    {9,5,6},
    {9,8,1,9},
    {4,5,2,6,5}
    最大和爲 2+9+9+9+6=35 (分治法)

常規的思路是應用分治法 找出每一層最大的項 統一相加獲得最大路徑
此處使用動態規劃的方法。算法

算法思想:

  • 1.將原問題分解爲子問題:原問題爲求解頂層到底層路徑最大數字和,分解爲每一層到底層路徑最大數字和,5個問題
  • 2.肯定狀態:使用 mstb (max_sum_to_bottom) 數組保存每一層次到底邊的最大和
  • 3.肯定初始態值:此處初始態爲底邊到底邊最大值 即mstb[4]
  • 4.肯定狀態轉移方程:mstb[i] = mstb[i + 1] + getMaxNumber(numbers[i]);

C++代碼

class MaxSum
{
    //數字三角形
    //此處使用初始化的數組 避免手動初始化的麻煩
    //此處僅作演示,若是用做其餘用途可改寫
    int numbers[5][5] = { 
        {2}, 
        {6,9}, 
        {9,5,6}, 
        {9,8,1,9}, 
        {4,5,2,6,5} 
    };
    int mstb[5];    //max_sum_to_bottom,某一層到達底邊最大的和,mstb[0]表示第一層到達底邊最大和
    public:
    //找出數組最大元素
    int getMaxNumber(int* const &numbers) {
        int max = 0;
        int length = sizeof(numbers);
        for (int i = 0; i < length;i++) {
            if (max < numbers[i]) {
                max = numbers[i];
            }
        }
        return max;
    }
    //輸出三角形
    void print() {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (numbers[i][j] > 0) {
                    cout << numbers[i][j] << ends;      //undo: 沒有對0以及負數作考慮
                }
            }
            cout << endl;
        }
    }
    //獲取從頂至底最大和
    int getMaxSum() {
        mstb[4] = getMaxNumber(numbers[5]);
        for (int i = 3; i >= 0; i--) {
            mstb[i] = mstb[i + 1] + getMaxNumber(numbers[i]);
        }
        return mstb[0];
    }
};

測試代碼

class Problem1Tester{
public:
    MaxSum max_sum;

    void getMaxNumber_Test() {
        max_sum.print();
        int numbers[5] = {8,5,9,5,1};
        cout << max_sum.getMaxNumber(numbers) << endl;
    }
    void getMaxSum_Test() {
        max_sum.print();
        cout << max_sum.getMaxSum() << endl;
    }
}tester1;

參考:
http://blog.csdn.net/baidu_28312631/article/details/47418773數組

相關文章
相關標籤/搜索