详细解析均在代码中:(附带算法执行时间)
#include<iostream>
#include<windows.h>
using namespace std;
//n个人(0~n-1),第i个人的体重为wi,每艘船的最大载重均为C,且最多只能乘2人,最少的船装所有的人
//如果n=0,船也为0
//如果n=1,则船也为1
//如果n>1 先装第一个,然后判断是否刚好装入,
//装完第一个人还有剩余重量就
// 找剩下人中重量小于等于剩余重量的,然后从中找一个最大的,和第一个人一起装入,然后判断下一个人
//第一个人刚刚好装入就
// 判断下一个人
//在此假设所有人的重量均不超过最大装载重量即wi<=C
int findMaxRest(int w[],int low,int high,int restC){
int t[high+1]={0},index=-1;
// cout<<restC<<"-----------restC"<<endl;
// 找到重量小于等于restC 的重量
for(int i=low;i<=high;i++){
if(w[i]<=restC){
t[i]=w[i];
// cout<<"t[]"<<t[i]<<endl;
}
}
int maxRest=0;
for(int i=low;i<=high;i++){
if(t[i]!=0){
maxRest=t[i];
break;
}
}
// cout<<maxRest<<"初始--------maxRest"<<endl ;
// 找出 小于等于restC的重量 中最大的
for(int i=low;i<=high;i++){
if(t[i]>=maxRest){
maxRest=t[i];
index=i;
}
}
// cout<<maxRest<<"最后--------maxRest"<<endl ;
// 返回下标
return index;
}
void solve(int w[],int low,int high,int C,int count,int &sum){
// 0个人
if(high-low<0){
sum+=0;
}
// 一个人
else if(low==high){
if(w[low]!=0){
sum+=1;
}
}
// 一个人以上
else{
// 如果装下后还有剩余
if(w[low]<C){
if(w[low]<=0){
// 已经装入,考虑下一个
solve(w,low+1,high,C,count,sum);
}else{
// 还未装入,现在装进,开始找寻剩下人中
// 重量小于等于C-刚刚装入那个人的重量中的最大值
// 2,3,4,5 C=7 那么装入第一个2,就找剩下的3,4,5中<=7-2即3,4,5中<=5的
// 3,4,5均<=5,找出他们当中最大的,5,这样2+5刚刚好等于7,充分装载
count+=1;
if(count==2){
int restC=C-w[low];
w[low]=0;
// 找到剩余人中重量<=restC,最大的
int index=findMaxRest(w,low+1,high,restC);
// cout<<"----------index="<<index<<endl;
if(index!=-1){
w[index]=0;
}
// 装满一艘船
sum+=1;
// 开始判断下一个人的重量
solve(w,low+1,high,C,1,sum);
}else if(count>2){
solve(w,low+1,high,C,1,sum);
}
}
}
// 如果刚刚好装下,那就开始判断下一个人
else if(w[low]==C){
sum++;
solve(w,low+1,high,C,1,sum);
}
// else if(w[low]>C){
// 重新装入一艘船
// cout<<"重新装入一艘船"<<endl;
// solve(w,low,high,C,1,sum);
// }
}
}
int main(){
_LARGE_INTEGER time_start; //开始时间
_LARGE_INTEGER time_over; //结束时间
double dqFreq; //计时器频率
LARGE_INTEGER f; //计时器频率
QueryPerformanceFrequency(&f);
dqFreq = (double)f.QuadPart;
//------------
int n,sum=0,C;
cout<<"请输入人数:";
cin>>n;
cout<<"请输入船的最大载重量:";
cin>>C;
int w[n];
cout<<"请输入每个人的重量:";
for(int i=0;i<n;i++){
cin>>w[i];
}
QueryPerformanceCounter(&time_start); //计时开始
solve(w,0,n-1,C,1,sum);
QueryPerformanceCounter(&time_over); //计时结束
cout<<"至少需要"<<sum<<"艘船"<<endl;
cout << "所用时间为" << 1000000 * (time_over.QuadPart - time_start.QuadPart) / dqFreq << "微秒" << endl;
}