设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wij是从供应商j 处购得的部件i的重量,cij是相应的价格。 试设计一个算法,给出总价格不超过d的最小重量机器设计。

输入格式:

第一行有3 个正整数n ,m和d, 0<n<30, 0<m<30, 接下来的2n 行,每行n个数。前n行是c,后n行是w。

输出格式:

输出计算出的最小重量,以及每个部件的供应商

输入样例:

3 3 4
1 2 3
3 2 1
2 2 2
1 2 3
3 2 1
2 2 2
 
结尾无空行

输出样例:

在这里给出相应的输出。例如:

4
1 3 1 


代码

#include<iostream>
using namespace std;
int n,m,d,minw=999,currw=0,currc=0;
int w[100][100],c[100][100];
int x[100],b[100];//记录选了哪个供货商
void backtrack(int t){
    if(t>n){
    //    cout<<currw<<endl;
        if(currw<minw){
            minw=currw;
            for(int i=1;i<=n;i++){
                b[i]=x[i];
            }
        }
    }
    else{//对第t个物品
        for(int i=1;i<=m;i++){//选择哪个供货商
            currw+=w[t][i];
            currc+=c[t][i];
            x[t]=i;
            //cout<<currw<<endl;
            if(currc<=d&&currw<=minw){
                backtrack(t+1);
            }
            currw-=w[t][i];
            currc-=c[t][i];
            x[t]=0;
            
        }
    }
}

int main(){
    cin>>n>>m>>d;
    for(int i=1;i<=n;i++){//从供应商j购得i的价格
        for(int j=1;j<=m;j++){
            cin>>c[i][j];
        }
    }
    for(int i=1;i<=n;i++){//从商品i在j供货商的质量
        for(int j=1;j<=m;j++){
            cin>>w[i][j];
        }
    }
    backtrack(1);
    cout<<minw<<endl;
    for(int i=1;i<=n;i++){
        cout<<b[i]<<" ";
    }
}

 

1.1   说明“最小重量机器设计问题"的解空间

解空间是m^n,由于每个商品有m种选择,有n种商品。

1.2   说明 “最小重量机器设计问题"的解空间树

一共有n层,每一层的节点有m个分支。

1.3   在遍历解空间树的过程中,每个结点的状态值是什么

当前总重量和当前总价格和当前选择的供货商

1.4对回溯的理解

对解空间树的深度优先遍历,和利用回溯对所有可能结果的遍历,回溯思想和算法容易得到但是回溯一般情况下时间复杂度较高,如果数据量比较大需要优秀的剪枝和限界函数缩小回溯的时间复杂度