有一架飛機,有n個人要登機,每個人的不滿值為登機時當前機艙在他所在行前方的人數總和,現在可以把飛機分為k個機艙,使不滿值總和最小
小h是機場登機的執行經理。他的工作是優化登機流程。飛機上的座位有s行,編號從1到s,每行有六個座位,標記為a到f。
今天 有n個乘客陸續登機,第i名乘客的座位在第ri行,則第i名乘客的登機難度等於在他登機時坐在1…r(i-1)行的乘客的人數。
例如,如果有10名乘客,他們的座位是6a,4b,2e,5f,2a,3f,1c,10e,8b,5a,那麼他們的登機困難分別是0,0,0,2,0,2,0,7,7,5,則難度總和為23 。
為了降低登機難度,小h想要將飛機座位劃分為k個區域。每乙個區域必須是連續的行。劃分成k個區域之後,乘客的登機順序不會改變,但是每個乘客的登機難度將只統計該乘客所在區域前面乘客的人數。
例如,在上面的例子中,如果我們把該平面分成兩個區域: 5-10行和1-4行 ,然後在第一區域中的乘客的座位為6a,5f,10e,8b,5a;在第二區域中的乘客的座位為4b,2e,2a,3f,1c,這種情況下,登機難度綜合為6。
現在,小h不知道該怎麼劃分這k個區域,才能讓乘客的登機難度總和最少。
輸入檔案第一行包含三個整數n,s,和k,下一行包含n個整數(1≤ri≤s),輸入保證每一行座位由最多有6名乘客。
輸出檔案包含乙個整數,表示登機可能的最小登機難度。
10 12 2
6 4 2 5 2 3 1 11 8 5
6
資料範圍
40%的資料,n<=100,s<=100
100%的資料,n<=1000,s<=1000, k<=50, k<=s
先用乙個s[i
][j]
s[i][j]
s[i][j
]來表示前i排人給第j排人造成的不滿值總和
然後用f[i
][j]
f[i][j]
f[i][j
]來表示第i行到第j行為乙個機艙的不滿值總和
則:
f[i]
[j]=f[i]
[j-1
]+s[j]
[j]-s[i-1]
[j];
//j-1行加上i~j行給第j行的不滿值
最後直接dp就可以了
#include
#include
#include
using
namespace std;
int n,m,k,l[
1050
],s[
1050][
1050
],f[
1050][
1050
],ans[
1050][
100]
;int
main()
for(
int i=
1;i<=m;
++i)
for(
int j=
1;j<=m;
++j)
s[i]
[j]+
=s[i-1]
[j];
//字首和
for(
int i=
1;i<=m;
++i)
for(
int j=
1;j<=m;
++j)
f[i]
[j]=f[i]
[j-1
]+s[j]
[j]-s[i-1]
[j];
//dp
memset
(ans,
127/3,
sizeof
(ans));
ans[0]
[0]=
0;for(
int i=
1;i<=m;
++i)
for(
int j=
1;j<=k;
++j)
for(
int c=j;c<=i;
++c)
//列舉從那個地方開始乙個新的機艙
ans[i]
[j]=
min(ans[i]
[j],ans[c-1]
[j-1
]+f[c]
[i])
;//dp
printf
("%d"
,ans[m]
[k])
;}
jzoj 3789( 棧 字首和)
sample input8 i 2 i 1 i 1 q 3 l d r q 2 sample output2 3題意 正在設計一種新型的編輯器,這種編輯器可以高效地處理整數序列。編輯器啟動時,序列為空,游標指向序列的頭部。編輯器支援下列 5 種操作 1.i x 把整數 x 插入到游標位置 2.d 刪...
字首和思想 JZOJ 100035 區間
傳送門 define runinstance x delete new x struct cheat1 在主函式中 if n 1000 runinstance cheat1 這樣就能做到不呼叫就不占用空間,呼叫不會爆棧,多次呼叫不會記憶體洩露。如果確實要多次呼叫,最好還是把迴圈寫裡面 對於25 的資...
HDU 5550 dp 字首和優化
有個大樓有n層,每層都有兩種人,一種喜歡的打球,一種喜歡游泳,現在要你在每一層要麼開設球館,要麼開設游泳館,分配完畢以後,打球的要到球館,游泳的要到游泳館,問最優分配下,所有人要移動的最短距離和是多少?dp i 0 1 表示第i層布置為0或1,且i 1層為1或0 與第i層相反 的最小代價。dp i ...