Republican

  :: 首页 :: 新随笔 :: :: 订阅 :: 管理 ::

今天剖析最大化石头堆问题,采用O(n^3)编程,问题不难,但很典型,也有更好的接近O(N^2)的代码进行优化。

问题如下:

在一个圆形操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最大得分。

思路剖析:

石头堆围成一个圆形操场,每次合并只能合并相邻堆,马上想到典型的邻接问题和菲波纳契数列,属于从局部最优到全局最优,并不断更新最大得分,直到运算完成才出结果。显然,最后的最大得分,并没有将随机输入进行综合考察,进行分布式,而是每一次的最大得分更新,都非常紧凑的依赖于前一次的计算,那么这就是经典菲波纳契规划问题。

流程如下:

选取对角线数组作为初始值----设置间隔递增-----动态更新每个间隔的合并值,并保存于数组-----计算完成,得出最大得分,和计算出最大得分的整条路线。

以下是本人的代码,稍微对经典DP问题进行修改,可以放入IDE尝试运行下,应该不成问题。这个输入最后求得的解,是2596,你可以把这个输入换成其他随机输入,

但是记得,这个一维数组的最后一个值,必须等于第一个初始值,追加上去。

public class RoundedStoneMaxMinHeap {

    public static RoundedStoneMaxMinHeap mMaxMin;

    public void bestOutput(int[] group) {
        int n = group.length;
        if (n > 0) {
            int[][] realTable = new int[n + 1][n + 1];
            int[][] lastTable = new int[n + 1][n + 1];

            for (int k = 1; k <= n; k++) {
                for (int j = 1; j <= n; j++) {
                    if (j == k) {
                        realTable[j][k] = group[k-1];
                    } else {
                        realTable[j][k] = 0;
                    }
                    lastTable[j][k] = 0;
                }

            }

            int total = 0;
            int temp = 0;
            for (int k = 1; k <= n; k++) {
                for (int left = 1; left <= n - k; left++) {
                    int right = left + k;
                    for (int i = left; i < right; i++) {
                        temp = realTable[left][i] + realTable[i + 1][right];
                        if (temp > realTable[left][right]) {
                            realTable[left][right] = temp;
                            lastTable[left][right] = i;
                            if(temp > total)
                                total = temp;

                        }
                    }
                    System.out.print(realTable[left][right] + ",");
                }
                System.out.println("");
            }
            System.out.print(total + " = max num");
        }

    }

    public static void main(String[] args) {

        int[] input = new int[] { 100, 80, 175, 220, 15, 3, 400, 872, 354, 57,
                86, 24, 110, 100 };
        mMaxMin = new RoundedStoneMaxMinHeap();

        mMaxMin.bestOutput(input);
    }

}

posted on 2012-08-17 23:04  Republist  阅读(286)  评论(0)    收藏  举报