算法训练 最大体积
时间限制:1.0s 内存限制:256.0MB
问题描述
每个物品有一定的体积(废话),不同的物品组合,装入背包会战用一定的总体积。假如每个物品有无限件可用,那么有些体积是永远也装不出来的。为了尽量装满背包,附中的OIER想要研究一下物品不能装出的最大体积。题目保证有解,如果是有限解,保证不超过2,000,000,000
如果是无限解,则输出0
如果是无限解,则输出0
输入格式
第一行一个整数n(n<=10),表示物品的件数
第2行到N+1行: 每件物品的体积(1<= <=500)
第2行到N+1行: 每件物品的体积(1<= <=500)
输出格式
一个整数ans,表示不能用这些物品得到的最大体积。
样例输入
3
3
6
10
3
6
10
样例输出
17
题目解析:
本题其实就是将所有数组合后,从无限大开始,找出第一个不能组成的数。
分两种情况考虑:
- 如果所有的物品体积的最大公约数不为1,则为无限解;
- 如果所有的物品体积的最大公约数为1,则从无限大开始,找出第一个不能组成的数。
eg:
示例代码:
1 #include<iostream> 2 using namespace std; 3 #define MAX_NUM 100000 4 5 int n; 6 int goods[11]; //保存物品的体积 7 int volume[MAX_NUM]; //保存物品能组成的所有体积 8 9 int gcd(int a,int b) //求两个数的最大公约数 10 { 11 if (a % b == 0) 12 return b; 13 else 14 return gcd(b, a % b); 15 } 16 17 int gcdAll() //求所有数的最大公约数 18 { 19 int temp = goods[0]; 20 for (int i = 1; i < n; i++) 21 { 22 temp = gcd(temp, goods[i]); 23 } 24 return temp; 25 } 26 27 int main() 28 { 29 cin >> n; 30 for (int i = 0; i < n; i++) 31 cin >> goods[i]; 32 33 if (gcdAll() == 1) //如果所有数的最大公约数为1,则有解,否则为无限解 34 { 35 volume[0] = 1; 36 for (int i = 0; i < n; i++) 37 { 38 for (int j = goods[i]; j <= MAX_NUM; j++) 39 { 40 if (volume[j - goods[i]] == 1) //i=0时,j为goods[0]的倍数; 41 //接下来,j为 goods[i]中物品体积值组合的结果 42 volume[j] = 1; 43 } 44 } 45 46 for (int i = MAX_NUM; i >= 0; i--) //逆序遍历所有的体积结果,将第一个不能组合的数输出后结束 47 { 48 if (!volume[i]) 49 { 50 cout<<i; 51 return 0; 52 } 53 } 54 } 55 56 cout<<"0"; //无限解 57 58 return 0; 59 }