1. 程式人生 > >清理垃圾

清理垃圾

表示 超過 def 行為 決定 文件 城市 std 輸入

題目鏈接

描述

小Hi和小Ho在兌換到了喜歡的獎品之後,便繼續起了他們的美國之行,思來想去,他們決定乘坐火車前往下一座城市——那座城市即將舉行美食節!

但是不幸的是,小Hi和小Ho並沒有能夠買到很好的火車票——他們只能夠乘坐最為破舊的火車進行他們的旅程。

不僅如此,因為美食節的吸引,許多人紛紛踏上了和小Hi小Ho一樣的旅程,於是有相當多的人遭遇到了和小Hi小Ho一樣的情況——這導致這輛車上的人非常非常的多,以至於都沒有足夠的位置能讓每一個人都有地方坐下來。

小Hi和小Ho本著禮讓他們的心情——當然還因為本來他們買的就是站票,老老實實的呆在兩節車廂的結合處。他們本以為就能夠這樣安穩抵達目的地,但事與願違,他們這節車廂的乘務員是一個強迫癥,每隔一小會總是要清掃一次衛生,而時值深夜,大家都早已入睡,這種行為總是會驚醒一些人。而一旦相鄰的一些乘客被驚醒了大多數的話,就會同乘務員吵起來,弄得大家都睡不好。

將這一切看在眼裏的小Hi與小Ho決定利用他們的算法知識,來幫助這個有著強迫癥的乘務員——在不與乘客吵起來的前提下盡可能多的清掃垃圾。

小Hi和小Ho所處的車廂可以被抽象成連成一列的N個位置,按順序分別編號為1..N,每個位置上都有且僅有一名乘客在休息。同時每個位置上都有一些垃圾需要被清理,其中第i個位置的垃圾數量為Wi。乘務員可以選擇其中一些位置進行清理,但是值得註意的是,一旦有編號連續的M個位置中有超過Q個的位置都在這一次清理中被選中的話(即這M個位置上的乘客有至少Q+1個被驚醒了),就會發生令人不愉快的口角。而小Hi和小Ho的任務是,計算選擇哪些位置進行清理,在不發生口角的情況下,清掃盡可能多的垃圾。

提示一:無論是什麽動態規劃,都需要一個狀態轉移方程!

提示二:好像什麽不對勁?狀態壓縮哪裏去了?

輸入

每個測試點(輸入文件)有且僅有一組測試數據。

每組測試數據的第一行為三個正整數N、M和Q,意義如前文所述。

每組測試數據的第二行為N個整數,分別為W1到WN,代表每一個位置上的垃圾數目。

對於100%的數據,滿足N<=1000, 2<=M<=10,1<=Q<=M, Wi<=100

輸出

對於每組測試數據,輸出一個整數Ans,表示在不發生口角的情況下,乘務員最多可以清掃的垃圾數目。

樣例輸入

5 2 1
36 9 80 69 85 

樣例輸出

201
#include <cstdio>
#include 
<iostream> #include <cstdlib> using namespace std; #define INF 0x3f3f3f3f//?иртсцсзmemset int n,m,q,wi[1005],how[1030],ans[1005][1030],ans2=0; int main() { how[1]=1;how[0]=0; for(int i=2;i<1030;i++) how[i]=how[i>>1]+(i&1); while(cin>>n>>m>>q) { for(int i=1;i<=n;i++) cin>>wi[i]; int len=1<<m; for(int i=1;i<=n;i++) { for(int j=0;j<len;j++) { if(how[j]<=q) ans[i][j]=max(ans[i-1][j>>1],ans[i-1][(j>>1)+(1<<(m-1))])+wi[i]*(j&1); ans2=max(ans2,ans[i][j]); // cout<<ans[i][j]<<" "<<i<<" "<<j<<endl; } } cout<<ans2<<endl; } return 0; }

清理垃圾