[hihoCoder] #1044 : 狀態壓縮·一

來源:互聯網
上載者:User

標籤:

時間限制:10000ms單點時限:1000ms記憶體限制:256MB描述

小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 136 9 80 69 85 
範例輸出
201

狀態壓縮的核心思想就是用二進位位來表示對應的位置的兩種狀態,問題在於怎麼知道哪些狀態是合法的哪些狀態是不合法的,所以在寫代碼前先要把判斷狀態轉移的情況考慮清楚。還是初始狀態的處理。

 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4  5 const int MAX_N = 1001; 6 const int MAX_M = 10; 7  8 int N, M, Q; 9 int w[MAX_N];10 int dp[MAX_N][1<<MAX_M];11 bool ok[1<<MAX_M];12 13 void init() {14     memset(ok, false, sizeof(ok));15     int val, cnt;16     for (int i = 0; i < (1<<M); ++i) {17         val = i; cnt = 0;18         while (val > 0) {19             cnt += (val & 1);20             val >>= 1;21         }22         ok[i] = (cnt <= Q);23     }24 }25 26 void solve() {27     memset(dp, -1, sizeof(dp));28     memset(dp[0], 0, sizeof(dp[0]));29     for (int i = 1; i <= N; ++i) {30         for (int j = 0; j < (1<<M); ++j) if (dp[i-1][j] != -1) {31             int s0 = ((j<<1) & ((1<<M) - 1));32             int s1 = ((j<<1 | 1) & ((1<<M) - 1));33             dp[i][s0] = max(dp[i][s0], dp[i-1][j]);34             if (ok[s1]) {35                 dp[i][s1] = max(dp[i][s1], dp[i-1][j] + w[i]);36             }37         }38     }39     int res = 0;40     for (int i = 0; i < (1<<M); ++i) {41         res = max(res, dp[N][i]);42     }43     cout << res << endl;44 }45 46 int main() {47     while (cin >> N >> M >> Q) {48         init();49         for (int i = 1; i <= N; ++i) {50             cin >> w[i];51         }52         solve();53     }54     return 0;55 }

 

[hihoCoder] #1044 : 狀態壓縮·一

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.