演算法題 陣列分段

2021-08-04 14:18:14 字數 1686 閱讀 9991

清潔工:假設有m個房間,清潔每個房間耗時用乙個陣列表示,10、20、30、40、50、60、70、80、90,安排n個清潔工,將連續的房間分成n份,每部分耗時求和,其最大值為此種分法的總耗時。求最快的耗時是多少。例如3個清潔工的話,10 20 30 40 50 | 60 70 | 80 90,此時是最快的,耗時為170。

題目:給定乙個陣列,和乙個值k,陣列分成k段。要求這k段子段和最大值最小。求出這個值。

解析:

使用dp[n][k]表示前n個房間,k個清潔工的最優解dp

[n][

k]=m

in⎧⎩

⎨⎪⎪⎪

⎪⎪⎪m

ax(d

p[0]

[k−1

],∑n

i=0a

[i])

max(

dp[1

][k−

1],∑

ni=1

a[i]

)...

max(

dp[n

][k−

1],∑

ni=n

a[i]

) 此題可以想象成把資料按順序裝入桶中,m即是給定的桶數,問桶的容量至少應該為多少才能恰好把這些數裝入k個桶中(按順序裝的)。

首先我們可以知道,桶的容量最少不會小於陣列中的最大值,即桶容量的最小值(小於的話,這個數沒法裝進任何桶中),假設只需要乙個桶,那麼其容量應該是陣列所有元素的和,即桶容量的最大值;其次,桶數量越多,需要的桶的容量就可以越少,即隨著桶容量的增加,需要的桶的數量非遞增的(二分查詢就是利用這點);我們要求的就是在給定的桶數量m的時候,找最小的桶容量就可以把所有的數依次裝入k個桶中。在二分查詢的過程中,對於當前的桶容量,我們可以計算出需要的最少桶數requiredpainters,如果需要的桶數量大於給定的桶數量k,說明桶容量太小了,只需在後面找對應的最小容量使需要的桶數恰好等於k;如果計算需要的桶數量小於等於k,說明桶容量可能大了(也可能正好是要找的最小桶容量),不管怎樣,該桶容量之後的桶容量肯定不用考慮了(肯定大於最小桶容量),這樣再次縮小查詢的範圍,繼續迴圈直到終止,終止時,當前的桶容量既是最小的桶容量。

#include 

#include

#include

#include

#include

#include

#include

using

namespace::std;

#define debug_

bool isok(vector

& vec,int k, long

long tmp_max)

}if (count>k)

return

false;

else

return

true;

}int func(vector

& vec,int k)

else

mid = left + ((right - left) >> 1);

}return right;

}int main()

;int a = ;

vec.insert(vec.begin(),a,a+11);

k = 3;

#else

#endif

cout

0;}

陣列(list)分組 分段

對乙個list進行分組,要求控制每組中的元素個數 1.使用切片分組 lst 1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1 lst可為空,最後返回值也為空 num 3 定義每組包含的元素個數 for i in range 0,len lst num print lst i i n...

陣列(list)分組 分段

對乙個list進行分組,要求控制每組中的元素個數 1.使用切片分組 lst 1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2,1 lst可為空,最後返回值也為空 num 3 定義每組包含的元素個數 for i in range 0,len lst num print lst i i n...

演算法 陣列分段和最大值最小問題

題目 給定乙個陣列,和乙個值k,陣列分成k段。要求這k段子段和最大值最小。求出這個值。n n 1 m n,k min j 1 i j n表示陣列長度,k表示陣列分成幾段。初始化條件 m 1,k a0 n 1 m n,1 ai i 0遞迴演算法擁有指數時間的複雜度,並且會重複計算一些m值。這類的演算法...