题目
有n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且∑wi <= c1 + c2。问是否有一个合理的装载方案,可将这n个集装箱装上这2艘轮船。如果有,找出一种装载方案
解析
思路:轻者先装,直到再装任何集装箱将使轮船载重量超过B时停止。
定理:对于任何正整数n,算法(轻者先装)对n个集装箱的实例得到最优解。
证明(数学归纳法):
(1)k=1,只有1个集装箱,其重量小于B。任何装法都只有一种方式,因此都是最优解。故轻者先装也是最优解。
(2)归纳假设:假设算法对于规模为n的输入都能得到最优解。
考虑规模为n + 1的输入,
是集装箱重量,其中
现在从N中取出最轻的集装箱,得到n规模的输入:
根据归纳假设,对于n个输入,N’,W’,B’的最优解为I’,即I’为N’,不含1的最优解,令
那么I必然是N的最优解,这也是算法对于N,W,C的解。
证明(反证法):I必然是N的最优解。
(1)构建最优解I*(N,含1):假设I不是N的最优解。则必然存在最优解I*,如果I中没有1,用I替代I中的第一个集装箱标号得到的解也是最优解(这是因为个数不变,故也是最优解),使得I为包含1的关于N的最优解,且| I | > | I |。
(2)构建最优解I*’(N’,不含1):因为I包含1的关于N的最优解,构建的 I’= I* - {1} 是不包含1的最优解,即关于N’、W’、C’的最优解(N’、W’、C’不包含1)。
注:此处利用反证法证明I*’= I* - {1} 是不包含1的最优解。
证明:若I*‘= I* - {1}不是不包含1的最优解,则存在最优解I*’’(N’,不含1),使得|I* ’| < | I*’’|,
即|I* ’+ {1} | < | I*’’+ {1}|,与I*’+ {1} = I为最优解相矛盾,因此I’= I* - {1}是不包含1 的最优解。
(3)构建的最优解I*’与归纳假设的最优解I’比较:由(1)| I* | > | I |得,|I*’|=|I*-{1}|>|I - {1}|=|I’|,与I’的最优性矛盾。
综上所述,假设命题不成立,原命题成立,即I必然是N的最优解。
装载问题(0-1背包问题)举例
w1 = 2,w2 = 2,w3 = 6,w4 = 5,w5 = 4
v1 = 6,v2 = 3,v3 = 5,v4 = 4,v5 = 6
B = 10
此解析部分采取了第十一次笔记的证明方式
设计
int n,k;//n表示一共有几个集装箱,k表示最大承受量
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)
for(int j=k;j>=a[i];--j){
dp[j]=max(dp[j],dp[j-a[i]]+1);
}
分析
时间复杂度为O(n*m)
源码
https://github.com/moshang1113/Loadind_problem