EOJ#1054. (算法作业5-2)机器设计

本文介绍了一个通过深度优先搜索解决的问题:给定多个部件组,每组包含3个部件,每个部件有成本和重量属性,在总成本不超过限制的情况下选择各组中的一个部件,使总重量最小。采用递归方式实现,复杂度为O(3^n)。
摘要由CSDN通过智能技术生成
 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int n, C;
 5 int nc, nw;
 6 int ans;
 7 int cost[60][3], weight[60][3];
 8 void dfs(int i) {
 9     if (i == n) ans= min(ans, nw);
10     for (int j = 0; j < 3; j++) {
11         nc += cost[i][j];
12         nw += weight[i][j];
13         if (nc < C&&nw<ans) 
14             dfs(i + 1);
15         nc -= cost[i][j];
16         nw -= weight[i][j];
17     }
18 }
19 int main() {
20     while (cin >> n >> C) {
21         for (int i = 0; i < n; i++) {
22             for (int j = 0; j < 3; j++) {
23                 cin >> weight[i][j] >> cost[i][j];
24             }
25         }
26         ans = 0x3f3f3f3f;
27         dfs(0);
28         cout << ans<<endl;
29     }
30     return 0;
31 }
View Code

 

题意:输入两个数n,C表示以下n行,之后每行6个数,两个数一组,第一个数表示该部件质量,第二个数表示该部件的花费。要求在总cost<C的条件下,从每行选一个部件,使得总质量最小。

思路:函数dfs[i]表示选第i个部件的过程,该过程中有三个部件要选择,因此需建立一个三次的循环,每次循环表示尝试选各种部件。

先看递归结束的条件,显然,当次数i==n时,表示已经选完最后一个部件。在进入函数前将结果ans设为无穷大INF,若每次递归结束时得到的质量nw<ans,则更新ans的值。故只有在每次达到递归结束条件时才会更新ans!!

再看循环中,每次循环即是假设已经选了该部件,故先将总质量,总花费更新一次。只有当花费未超标,且当前质量小于已知ans时(毕竟若还未选完就已经大于ans,则无继续必要),再进入下一层递归,即在选该部件的情况下继续挑选其它部件。之后还应还原会原先状态,表示未选该部件,以便继续尝试其它部件。

由于dfs尝试了每一种挑选可能,故复杂度为O(3^n)。

代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 int n, C;
 5 int nc, nw;
 6 int ans;
 7 int cost[60][3], weight[60][3];
 8 void dfs(int i) {
 9     if (i == n) ans= min(ans, nw);
10     for (int j = 0; j < 3; j++) {
11         nc += cost[i][j];
12         nw += weight[i][j];
13         if (nc < C&&nw<ans) 
14             dfs(i + 1);
15         nc -= cost[i][j];
16         nw -= weight[i][j];
17     }
18 }
19 int main() {
20     while (cin >> n >> C) {
21         for (int i = 0; i < n; i++) {
22             for (int j = 0; j < 3; j++) {
23                 cin >> weight[i][j] >> cost[i][j];
24             }
25         }
26         ans = 0x3f3f3f3f;
27         dfs(0);
28         cout << ans<<endl;
29     }
30     return 0;
31 }
View Code

 

转载于:https://www.cnblogs.com/woria/p/10597240.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值