演算法報告六 裝載問題

2021-09-30 16:38:21 字數 1702 閱讀 9023

16122020   鐘順源

將n個體積分別為wi貨櫃放置在容量分別為c1,c2的輪船中,問是否能有個合理放置的方案,若有,則輸出字典序最大的方案。

題目可以轉換為有n個元素,對於某個元素,有取或不取兩個操作,取的貨櫃總體積不超過c1,不取的貨櫃總體積不超過c2,取或不取的問題可以dp做,爆搜當然也可以,但既然學到的搜尋,就爆搜+減枝

因為要記錄最佳的方案情況,而更新一次最佳方案需要o(n

)o(n)

o(n)

的複雜度搜尋每一種方案需要o(2

n)

o(2^n)

o(2n

),所以總的複雜度是o(n

×2n)

o(n×2^n)

o(n×2n

)的複雜度,那如何將複雜度降為o(2

n)

o(2^n)

o(2n)?

做加法不做乘法

先找出第一艘船能裝的滿足條件的最多貨物,之後在按先搜1再搜0的順序搜尋第乙個滿足條件的組合,因為是按1,0的順序搜尋的,所以第乙個滿足條件的方案一定是字典序最大的。

簡單來說就是 兩次dfs。

#includeusing namespace std;

const int n=30;

int a[n],b[n];

int bestw=0;//

int n; int c1,c2;

int all;

int fac[n],pre[n];

int cnt=0;

setans;

void dfs1(int pos,int sum)

if(sum + fac[pos] < bestw) return ;

if(sum + a[pos] <= c1)

dfs1(pos+1,sum+a[pos]);

if(pre[pos] - sum <= c2)

dfs1(pos+1,sum);

}void dfs2(int pos,int sum,string xx)

if(sum + fac[pos] < bestw) return ;

if(sum + a[pos] <= c1)

dfs2(pos+1,sum+a[pos],xx+'1');

if(ans.size()) return ;

if(pre[pos] - sum <= c2)

dfs2(pos+1,sum,xx+'0');

}int main()

fac[n+1] = 0;

for(int i=n;i>=1;i--) fac[i] = fac[i+1] + a[i];

scanf("%d%d",&c1,&c2);

printf("case %d\n",++cas);

bestw=-1;

dfs1(1,0);

dfs2(1,0,"");

if(bestw==-1)

cout《這次實驗還是蠻有意思的,之前一直沒有考慮到更新的答案的開銷如何消除,但沒想到只要先處理出答案,在去搜字典序最大的路徑就可以了,兩個dfs的複雜度都是o(2

n)

o(2^n)

o(2n

),所以最後的總的複雜度也是o(2

n)

o(2^n)

o(2n)。

裝載問題 回溯演算法

題目描述 有一批共n個貨櫃要裝上2艘載重量分別為c1和c2的輪船,其中貨櫃i的重量為wi。裝載問題要求確定,是否有乙個合理的裝載方案可將這n個貨櫃裝上這2艘輪船。如果有,找出一種裝載方案。題目出自 計算機演算法設計與分析 第三版 王曉東 這是乙個典型的回溯演算法問題。如下 template clas...

演算法作業(裝載問題)

有n個貨櫃要裝上2艘載重量分別為c1和c2的輪船,其中第i個貨櫃的重量為wi,要求確定是否有乙個合理的裝載方案可將這個貨櫃裝上這2艘輪船。如果有,找出一種裝載方案。注意,在滿足的條件下才可能將這個貨櫃裝上這2艘輪船。輸入有若干組測試資料 不超過20組 每組測試資料有3行 其第1行上是貨櫃個數n,n ...

回溯演算法 裝載問題

給定n個貨櫃要裝上一艘載重量為c的輪船,其中貨櫃i的重量為wi。貨櫃裝載問題要求確定在不超過輪船載重量的前提下,將盡可能多的貨櫃裝上輪船 貪心演算法中的裝載問題討論的是裝載件數 本題討論的是最大裝載重量。由於貨櫃問題是從n個貨櫃裡選擇一部分貨櫃,假設解向量為x x1,x2,xn 其中xi xi 1表...