这是我参与8月更文挑战的第1天,活动详情查看: 8月更文挑战
算法设计与分析题目1:
n个部件:1...n
m个供应商:1...m
每种部件可从m个供应商中购得
w[i][j]:从供应商j,买部件i的重量(weight)
c[i][j]:是价格(cost)
目的:计算总价格不超过cost,总重量最小
输入:
(1)n m cost
(2)二维数组:重量,w[n][m],n行m列
(3)二维数组:价格,c[n][m],n行m列
输出:
(1)n个部件分别从哪些供应商购得
(2)总重量是多少
核心代码及注释:
/* step:当前第几个部件,price:当前价格,weight:当前重量 */
void dfs(int step, int price, int weight) {
/* 退出dfs */
if (price > cost) return;
/* 如果在main中已完成位置重合,跳过 */
while (step < n && flag[step]) ++step;
/* 退出dfs */
if (step >= n) {//如果遍历到最后1个部件,算法完成,输出结果
if (weight < min_weight) {
min_weight = weight;
for (int i = 0; i < n; i++)
out[i] = flag[i];
}
return;
}
/* 继续dfs */
for (int j = 0; j < m; j++) {
flag[step] = j + 1;
dfs(step + 1, price + c[step][j], weight + w[step][j]);
}
}
int main() {
/* 先找出重量最小,价格最小的情况 */
//①找到则节省时间,跳出暴力破解
//②找不到就暴力破解
int weight = 0, price = 0;//累计当重量min和价格min位置重合时的重量和价格
for (int i = 0; i < n; i++) {//遍历每个部件1...n
int min_w = 0x7fffffff;//临时存最小重量
int min_c = 0x7fffffff;//临时存最小价格
int location_w = -1;//临时存最小重量供应商位置
int location_c = -1;//临时存最小价格供应商位置
/* 找出最小重量,最小价格 */
for (int j = 0; j < m; j++) {//遍历每个部件的供应商1...m
if (w[i][j] < min_w) {
min_w = w[i][j];//保存第i部件的最小重量
location_w = j;
}
if (c[i][j] < min_c) {
min_c = c[i][j];//保存第i部件的最小价格
location_c = j;
}
}
/* 如果2个最小位置重合,那后面就不需要暴力 */
if (location_w == location_c) {
flag[i] = location_w + 1;//存第i个部件的最小重量的供应商位置
price += min_c;//累计最小价格
weight += min_w;//累计最小重量
}
}
/* 暴力破解 */
dfs(0, price, weight);
for (int i = 0; i < n; ++i)
cout << out[i] << ' ';
cout << '\n' << min_weight << endl;
system("pause");
return EXIT_SUCCESS;
}
试验: 输入:
/* 定义问题数据 */
#define N 100
int w[N][N] = {
{1,2,3},
{3,2,1},
{2,3,2}
};
int c[N][N] = {
{1,2,3},
{5,4,2},
{2,1,2}
};
int n = 3, m = 3, cost = 7;
输出:结果正确