Farmer Brown's cows are up in arms, having heard that McDonalds is considering the introduction of a new product: Beef McNuggets. The cows are trying to find any possible way to put such a product in a negative light.
One strategy the cows are pursuing is that of `inferior packaging'. ``Look,'' say the cows, ``if you have Beef McNuggets in boxes of 3, 6, and 10, you can not satisfy a customer who wants 1, 2, 4, 5, 7, 8, 11, 14, or 17 McNuggets. Bad packaging: bad product.''
Help the cows. Given N (the number of packaging options, 1 <= N <= 10), and a set of N positive integers (1 <= i <= 256) that represent the number of nuggets in the various packages, output the largest number of nuggets that can not be purchased by buying nuggets in the given sizes. Print 0 if all possible purchases can be made or if there is no bound to the largest number.
The largest impossible number (if it exists) will be no larger than 2,000,000,000.
PROGRAM NAME: nuggets
INPUT FORMAT
Line 1: | N, the number of packaging options |
Line 2..N+1: | The number of nuggets in one kind of box |
SAMPLE INPUT (file nuggets.in)
3 3 6 10
OUTPUT FORMAT
The output file should contain a single line containing a single integer that represents the largest number of nuggets that can not be represented or 0 if all possible purchases can be made or if there is no bound to the largest number.SAMPLE OUTPUT (file nuggets.out)
17
这里提供一种略有些不同的思路 首先,如果gcd(a,b,c,d……) != 1,那么显然无穷多解 如果其中有一个数是1,显然0 然后考虑分组,按照%最小的数分组,然后构建边跑最短路 如果某一组数字中有一个满足可以被组合,求出这个数最小是多少 那么显然,不能组合的就是 这个数-最小的数字 找出这些数中的最大值,就是答案。
/* ID:cqz15311 LANG:C++ PROG:nuggets */ #include<cstdio> #include<cmath> #include<algorithm> #include<cstdlib> #include<cstring> using namespace std; int n,dist[505],f,m; int a[15]; int q[5505]; int front,rear; int main(){ freopen("nuggets.in","r",stdin); freopen("nuggets.out","w",stdout); scanf("%d",&n); m = 0x3fffff; for (int i=1;i<=n;i++){ scanf("%d",&a[i]); m = min(m,a[i]); } f = a[1]; for (int i=2;i<=n;i++) f = __gcd(f,a[i]); if ((f != 1) || (m == 1)){ printf("%d\n",0); } else{ front = rear = 0; memset(dist,-1,sizeof(dist)); for (int i=1;i<=n;i++){ if ((dist[a[i] % m] == -1) || (dist[a[i] % m] != -1) && (a[i] < dist[a[i] % m])){ dist[a[i] % m] = a[i]; q[rear++] = a[i] % m; } } while (front < rear){ int u = q[front++]; for (int i=1;i<=n;i++){ int v = (u + a[i]) % m; if ((dist[v] == -1) || (dist[v] != -1) && (dist[v] > dist[u] + a[i])){ dist[v] = dist[u] + a[i]; q[rear++] = v; } } } int ans = 0; for (int i=0;i<m;i++){ ans = max(ans,dist[i] - m); } printf("%d\n",ans); } fclose(stdin); fclose(stdout); }