题目
有 件货物, 第
件重
吨,另有
个集装箱,每个集装箱可以装重量不超过
吨的货物。
货物不能分拆,请判断这 个集装箱能否装下所有货物。
解题思路
先确定最重的货物重量
,如果
,因为货物不能分拆,所以这些集装箱不能装下这个货物。
再比较
和
,如果
,那么每个货物都可以单独放置一个集装箱,所以答案是 Yes。
如果
,使用回溯算法。
表示第
个集装箱当前装下货物的重量。
回溯算法:
试着将第 个货物放到第
个集装箱中,如果可以装下,就装进去,
,然后装第
个货物。
如果装完了所有货物,就返回 true。
如果上述方案失败,就返回前一步,重置成之前的状态,,将第
个货物放到第
个集装箱中。重复上述步骤。
如果试完了所有集装箱,而货物还没装完,返回 false。
装第 个货物时,可以只考虑前
个箱子,假如使用了
个箱子,至少会出现一个空箱子。
C++代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> w, a;
int n, x, W;
bool dfs(int k){
if(k==n)
return true;
for(int i=0; i<min(k+1,x); ++i){
if(a[i]+w[k]<=W){
a[i]+=w[k];
if(dfs(k+1))
return true;
a[i]-=w[k];
}
}
return false;
}
int main(){
int T;
cin >> T;
while(T--){
cin >> n >> x >> W;
w.resize(n);
int ma = 0;
for(int i=0; i<n; ++i){
cin >> w[i];
ma = max(ma, w[i]);
}
if(ma>W){
cout << "No" << endl;
continue;
}
if(n<=x){
cout << "Yes" << endl;
continue;
}
a.resize(x,0);
for(int i=0; i<x; ++i) a[i]=0;
if(dfs(0))
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
} 
京公网安备 11010502036488号