多重背包的二進制優化


今天在寫到多重背包的題的時候,本來想着按老方法一個個循環添加,沒想到這次超時了,就找下了下優化的方法,果然找到了

二進制優化

不得不說是真的牛逼,智商差距啊 智商差距啊!

好了,下面正題

 

首先,之前的方法是這樣的

假如我們 東西的價值是  Val[] 數組,對應數量是 Num[]數組 ,一共有 n件東西

那按照老方法是  把數量大於一件的,全部抽出來添加在 Val[]數組,也就是說我們把這些大於一件的東西,全部當成   新的一件並且價值相同的 東西。代碼如下:

#include<iostream>
using namespace std;
int main()
{
    int n;
    int wei[100], val[100], num[100];//物品的重量、價值、數量
    cin >> n;//讀入一共有幾種物品

    //讀入物品的信息
    for (int i = 1; i <= n; i++) {
        cin >> wei[i] >> val[i] >> num[i];
    }
    //下面是核心
    int tail = n;
    //從第一件產品開始枚舉
    for (int j = 1; j <= n; j++) {
        while (num[j]!=1)//如果該件產品的數量不是1件的話
        {
            tail++;//尾部加一
            //添加在尾部,補充好物品的信息
            wei[tail] = wei[j];
            val[tail] = val[j];
            num[tail] = 1;
        }
    }
    return 0;
}

這種方法應該也就我這種腦子想的,其實還有點問題,就是如果物品數是0的話,還得再加一個判斷把該物品刪除了。

然后就是TLE了,所以下面是優化的方法!

 

——————————————————分割線——————————————————————————————

 

二進制優化

簡單來說,就是把一個數字分成   (1  2  4  8.........最大數) 這樣下去的類型

為什么呢? 因為這些數字可以組成(1~最大數)中的任何一個數

這也就意味着,我們可以實現組合

其實思路還是和上面的一樣,還是把這些抽出來變成一個新的產品,不過  重量和價值   有所不同。

例如變成:

一件 val[i]*1    wei[i]*1

一件  val[i]*2   wei[i]*2

一件  val[i]*4 wei[i]*4

一件  val[i]*8    wei[i]*8

以此類推,這樣比如我們要放  該產品4件   那就可以用我們 之前抽出來的變成的    新產品    代替。

        for (int i = 1; i <= spe; i++)
        {
            //核心代碼
            for (int j = 1; num[i] > j; j <<= 1)//注意j用到二進制位移
            {
                sale[++count] = sale[i] * j;
                wei[count] = wei[i] * j;
                num[i] -= j;
            }
            wei[i] = wei[i] * num[i];
            sale[i] = sale[i] * num[i];
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM