演算法分析課設(七)大理石分割問題(多重揹包)

2021-10-14 09:39:32 字數 2261 閱讀 5297

有若干塊大理石,其大小及美觀程度不一,為了比較客觀的分割這些大理石,我們需要先給這些大理石乙個評分,評分分為6個等級,分別用1~6的數字來表示。現希望將這些大理石分成兩部分,使每部分的評分之和相同。

輸入:

輸入一行,包括6個數,分別是每個等級的大理石的數量。每種等級的大理石數量不超過20000.

輸出:

如果這些大理石能否分割成評價等級之和相同的兩部分,則輸出true,否則輸出false.

樣例輸入:

1 0 1 2 0 0

樣例輸出:

false

1、寫出求解樣例輸入時的求解過程。

2、寫出演算法分析過程,編寫程式求解上述問題,並分析演算法的時間複雜度。

這是力扣關於01揹包的講解,看懂了就知道怎麼做這道題了。

本題是多重揹包問題,只要會01揹包就能做多重揹包。所以,我們不用遞迴,用動態規劃來做。只用填一張二維表,先不說為什麼。

題目輸入是「1 0 1 2 0 0」,也就是有1個等級為1的大理石,有1個等級為3的,有2個等級為4的。把它轉化為大理石的陣列:num=[1,3,4,4]。要分割為兩半,則每一部分是(1+3+4+4)/2=6個等級,用這四個數能湊出6我們就能返回true。

現在構建二維表,我們用二維陣列dp表示。行是大理石陣列num的元素,列是需要湊出的等級,**則是判斷true還是false。如果我們只湊6,為什麼要把1到5都寫出來呢,後面再說。

num123

4561

344現在開始一行一行地填表。

1、填第一行的時候,第乙個空格代表揹包裡只有1,要湊出1,明顯是可以的,dp[num[0]][1]填true。後面的2到6是湊不出來的,都是false。

2、填第二行的時候,注意,這裡不是揹包裡只有3的意思,而是1和3。

3、填第三行的時候,代表揹包裡有1,3,4。

4、填第四行的時候,代表揹包裡有1,3,4,4

所以,為什麼湊6需要把1-5都列出來,就是為了查揹包裡有沒有其他大理石能和當前大理石一起湊到某個數。

第一行我們總是只能填乙個t,就是行=列的時候,因為乙個數只能湊它本身的數。在填第二行的時候,對於小於3的列,直接照抄上一行;對於等於3的列,直接填t;對於大於3的列,用列減3得到的差,去查上一行且列等於這個差的格仔(也就是看揹包裡有沒有等於這個差的數),如果是t,代表揹包裡有這個數,填t,如果是f代表揹包裡沒有這個數,填f。

完整**如下:(時間緊迫,不注釋了,想著那個填表就知道咋寫了)

#include#include#include#include#define maxn 120000

bool distribution(int* num, int numsize);

int main()

; int n;

int cnt=0;

// 輸入6個數

for(int i=1;i<=6;i++)

// 表來了,就是它,二維陣列dp

int dp[numsize][target + 1];

// 初始化dp為全f

memset(dp, 0, sizeof(dp));

// 填第一行,行和列相等的就是t

dp[0][num[0]] = true;

// 從第二行開始填

for (int i = 1; i < numsize; i++) else }}

// 返回**右下角那個格,因為一旦上一行為t,後面所有行都為t

return dp[numsize - 1][target];

}

演算法的時間複雜度為這不是最優的,最優的是把dp變成一維陣列。因為某個格仔是t,則同列的後面每行都是t,所以dp不是二維的也可以。這種辦法的時間複雜度變成

七大排序演算法

氣泡排序 void bubble int a,int n 選擇排序 void select sort int a,int n n為陣列a的元素個數 將第i 小的數,放在第i 個位置 如果剛好,就不用交換 if i min index 插入排序 typedef int elementtype void...

七大排序演算法

七大排序分類 插入排序 直接插入排序 穩定 希爾排序 不穩定 選擇排序 簡單選擇排序 穩定 堆排序 不穩定 交換排序 氣泡排序 穩定 快速排序 不穩定 歸併排序。直接插入排序 時間複雜度 o n 2 演算法穩定性 穩定void straightinsertsort int a,int n 氣泡排序 ...

七大排序演算法

首先回顧下各種排序的主要思路 一 氣泡排序 氣泡排序主要思路是 通過交換使相鄰的兩個數變成小數在前大數在後,這樣每次遍歷後,最大的數就 沉 到最後面了。重複n次即可以使陣列有序。氣泡排序改進1 在某次遍歷中如果沒有資料交換,說明整個陣列已經有序。因此通過設定標誌位來記錄此次遍歷有無資料交換就可以判斷...