使用小于O(N ^ 4)的K矩形最小化总面积

时间:2017-01-03 09:24:14

标签: algorithm dynamic-programming

鉴于N个数字的序列越来越多(直到T),我们可以使用最多K个矩形(从位置0开始放置),例如对于序列中的第i个值v,在位置中存在矩形[v ,T)身高至少为i + 1.

矩形的总面积应该是满足上述要求的最小值。

示例:给定序列[0,3,4],T = 5和K = 2我们可以使用:

  • 从0到2的高度为1的矩形(因此面积为3)
  • 从3到4的矩形,高度为3(因此面积为6)。

使用最多2个矩形,我们不能得到小于9的总面积。

使用DP可以解决此问题。

int dp[MAXK+1][MAXN][MAXN];
int sequence[MAXN];
int filldp(int cur_idx, int cur_value, int cur_K) {
    int res = dp[cur_K][cur_idx][cur_value];
    if (res != -1) return res;

    res = INF;
    if (cur_idx == N - 1 && cur_value >= N)
        res = min(res, (T - seq[cur_idx]) * cur_value);
    else {
        if (cur_idx < N - 1 && cur_value >= cur_idx + 1) {
            int cur_cost = (seq[cur_idx + 1] - seq[cur_idx]) * cur_value;
            res = min(res, cur_cost + filldp(cur_idx + 1, cur_value, cur_K);
        }

        // Try every possible height for a rectangle
        if (cur_K < K)
            for (int new_value = cur_value + 1; cur_value <= N; new_value++)
                res = min(res, filldp(cur_idx, new_value, cur_K + 1));
    }
    dp[cur_K][cur_idx][cur_value] = res;
    return res;
}

不出所料,这种DP方法并不是很快,可能是因为for周期。但是,据我所知,此代码不应超过MAXK * MAXN * MAXN有意义的调用(即,dp中的每个单元不多)。 MAXK和MAXN都是200,所以dp有8百万个单元,这不算太多。

我错过了什么吗?

更新:正如Saeed Amiri所指出的那样(谢谢!),代码使得N ^ 2 * K有意义的调用,但每个调用都是O(N)。然后整个算法是O(N ^ 3 * K)= O(N ^ 4)。

我们可以做得更好吗?

0 个答案:

没有答案