鉴于N个数字的序列越来越多(直到T),我们可以使用最多K个矩形(从位置0开始放置),例如对于序列中的第i个值v,在位置中存在矩形[v ,T)身高至少为i + 1.
矩形的总面积应该是满足上述要求的最小值。
示例:给定序列[0,3,4],T = 5和K = 2我们可以使用:
使用最多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)。
我们可以做得更好吗?