蓝桥杯 最大体积 数论 dp

问题描述
  每个物品有一定的体积(废话),不同的物品组合,装入背包会战用一定的总体积。假如每个物品有无限件可用,那么有些体积是永远也装不出来的。为了尽量装满背包,附中的OIER想要研究一下物品不能装出的最大体积。题目保证有解,如果是有限解,保证不超过2,000,000,000
  如果是无限解,则输出0
输入格式
  第一行一个整数n(n<=10),表示物品的件数
  第2行到N+1行: 每件物品的体积(1<= <=500)
输出格式
  一个整数ans,表示不能用这些物品得到的最大体积。
样例输入
3
3
6
10
样例输出
17
不太理解,待复习。
转载于https://www.cnblogs.com/cao-lei/p/7218782.html
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_NUM = 1000000;
 4 int n;
 5 int goods[15]; //保存物品的体积 
 6 int volume[MAX_NUM]; //保存物品能组成的所有体积
 7 int gcd(int a,int b) { //求两个数的最大公约数 
 8     if (a % b == 0) {
 9         return b;
10     } else {
11         return gcd(b, a % b);
12     }
13 }
14 int gcdAll() { //求所有数的最大公约数 
15     int t = goods[0];
16     for (int i = 1; i < n; i++) {
17         t = gcd(t, goods[i]);
18     }
19     return t;
20 }
21 int main() {
22     cin >> n;
23     for (int i = 0; i < n; i++) {
24         cin >> goods[i];
25     }
26     if (gcdAll() == 1) { //如果所有数的最大公约数为1,则有解,否则为无限解 
27         volume[0] = 1;
28         for (int i = 0; i < n; i++) {
29             for (int j = goods[i]; j <= MAX_NUM; j++) {
30                 if (volume[j - goods[i]] == 1) {
31                     //i=0时,j为goods[0]的倍数;
32                     //接下来,j为 goods[i]中物品体积值组合的结果
33                      volume[j] = 1;                                
34                 } 
35             }
36         }
37         for (int i = MAX_NUM; i >= 0; i--) { //逆序遍历所有的体积结果,将第一个不能组合的数输出后结束 
38             if (!volume[i]) {
39                 cout << i << endl;
40                 return 0;
41             }
42         }
43     } 
44     cout << 0 << endl; //无限解    
45     return 0;
46 }

 

 
posted @ 2020-04-10 13:00  kyk333  阅读(190)  评论(0)    收藏  举报