算法装载问题:n个人,第i个人的体重为wi,每艘船的最大载重均为C,且最多只能乘2人,用最少的船装所有的人 ,求船数

详细解析均在代码中:(附带算法执行时间)

#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;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值