POJ 1014 Dividing 背包

來源:互聯網
上載者:User

標籤:blog   使用   2014   art   問題   cti   

這道題使用多重背包,不過其實我也不太明白為什麼叫這個名字。

因為感覺不是什麼多重,而是物體的分解問題。

就是比如一個物體有數量限制,比如是13,那麼就需要把這個物體分解為1, 2, 4, 6

如果這個物體有數量為25,那麼就分解為1, 2, 4, 8, 10

看出規律嗎,就是分成2的倍數加上位元,比如6 = 13 - 1 - 2 - 4, 10 = 25 - 1 - 2 - 4 - 8,呵呵,為什麼這麼分解?

因為這樣分解之後就可以組合成所有1到13的數,為25的時候可以組合成所有1到25的數啦。

就是這麼一個分解物體,最後組合的問題,叫成什麼多重背包罷了。

不明白?

給多幾個數字組合:

31分解 1, 2, 4, 8, 16

32分解1,2,4, 8, 16, 1

33分解1,2,4,8,16,2

如此分解的。

想通了,其實一點難度都沒有,和一般背包問題一樣做法了。

#include <stdio.h>#include <vector>using std::vector;const int SIZE = 7;int N[SIZE];bool findPartition(){int sum = 0;for (int i = 1; i < SIZE; i++)sum += i * N[i];if (sum & 1) return false;int half = sum >> 1;vector<bool> part(half+1);part[0] = true;for (int i = 1; i < SIZE; i++){int k = 1;for ( ; (k<<1) <= N[i]; k <<= 1){//例:13分解為1,2,4,6可以組合為1到13個物品,故此考慮了所有情況了for (int j = half; j >= k*i; j--){if (part[j-k*i]) part[j] = true;}}k = N[i] - k + 1;for (int j = half; j >= k*i; j--){if (part[j-k*i]) part[j] = true;}}return part[half];}int main(){int t = 1;while (true){int val = 0;for (int i = 1; i < SIZE; i++){scanf("%d", &N[i]);val += N[i];}if (!val) return 0;if (findPartition()) printf("Collection #%d:\nCan be divided.\n\n", t++);else printf("Collection #%d:\nCan't be divided.\n\n", t++);}return 0;}



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.