动态编程:平衡分区

时间:2014-12-10 12:50:01

标签: java algorithm

我想为此问题实现动态编程算法: 输入:给定的非负数排列S {S1 ....... Sn}

我们想要将S分成2个子集S1和S2并最小化| sum(S1)-sum(S2)|,然后以相同的方式对2个子集进行分区,当我们到达具有2或1个元素的子集时我们停止()我们必须保留S元素的顺序。)

示例:S = {1,2,2,3,4}输出{{{1,2} {2}} {3,4}}

this article的帮助下,这是我的实施:

static String partition(int s[], int db,int fn)
{
    int n = (fn-db) +1;
    String res ="";
    if (n<=2){
        res +="[";
        for(int l =db ;l<=fn;l++) res+=s[l];
        res +="]";
        return res;
    }
    int[][] m= new int [n+1][3];                 /* DP table for values */             
    int[][] d= new int [n+1][3];                 /* DP table for dividers */ 
    int [] p = new int [n+1];                    /* prefix sums array */
    int cost;                               /* test split cost */
    int i,x = 0;                              /* counters */

    p[0] = 0;                               /* construct prefix sums */
    for (i=1; i<=n; i++) 
        p[i]=p[i-1]+s[(db-1)+i];

    for (i=1; i<=n; i++) 
        m[i][1] = p[i];    /* initialize boundaries */
        m[1][2] = s[db];


    for (i=2; i<=n; i++){                    /* evaluate main recurrence */
            m[i][2] = Integer.MAX_VALUE;
            for (x=1; x<=(i-1); x++) {
                cost = Math.max(m[x][1], p[i]-p[x]);
                if (m[i][2] > cost) {
                    m[i][2] = cost;
                    d[i][2] = db+(x-1);
                }
            }
     }
    return res +="["+partition(s,db,d[n][2])+partition(s,d[n][2]+1,fn)+"]";

}

public static void main(String[] args) {
    int []set ={2,1,1,1,5};
    System.out.print(partition(set,0,set.length-1));
}
  1. 我的实现是好的还是还有另一个动态编程解决方案whitout递归调用?

  2. 我无法计算这个算法的复杂性,我尝试使用Master定理T(n)= aT(nb)+ f(n),但我现在不用n / b每个子问题的大小2递归调用。

    3.如果我们可以改变元素的顺序,我们可以做同样的分区吗?

1 个答案:

答案 0 :(得分:0)

以这种方式思考:在最坏的情况下,你有一个数组,其中每个索引i包含值2 i 。在这种情况下,拆分仅将长度减小一个,这意味着递归深度在n中是线性的。在每个级别,您执行O(n)工作,因此总复杂度为O(n 2 )。幸运的是,这样的阵列在实践中会非常短暂,因为我们通常不会考虑这么大的数字,因此现实世界的性能通常会更好。当权重稍微平衡时,您应该具有O(n log n)性能。

关于第一个问题,我不确定你对“好人”的意思。

编辑:通过对要拆分数组的位置执行二进制搜索,可以提高算法的效率。这是可能的,因为必须保留订单。

相关问题