算法设计与分析学习笔记01 | 8月更文挑战

144 阅读2分钟

这是我参与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;

输出:结果正确

图片1.png