USACO 4.1 Beef McNuggets(DP)
以前一次比赛中遇见过。一直以为价值为a和b的两种钱币,最大组不成的是a*b-a-b。。。后来发现前提是a和b两个是互质的。
知道这个结论,这个题目就转化为背包了。如何证明,我没想出来,也有点怀疑正确性。不过代码数据都过了。
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: nuggets 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <iostream> 9 #include <cmath> 10 #include <algorithm> 11 using namespace std; 12 int p[11]; 13 int dp[256*256]; 14 int gcd(int a,int b) 15 { 16 return b == 0 ? a:gcd(b,a%b); 17 } 18 int main() 19 { 20 int n,i,j,v,key,flag; 21 freopen("nuggets.in","r",stdin); 22 freopen("nuggets.out","w",stdout); 23 scanf("%d",&n); 24 for(i = 1;i <= n;i ++) 25 scanf("%d",&p[i]); 26 if(n == 1) 27 { 28 printf("%d\n",p[1]-1); 29 return 0; 30 } 31 sort(p+1,p+n+1); 32 key = p[1]; 33 for(i = 2;i <= n;i ++) 34 key = gcd(key,p[i]); 35 if(key != 1) 36 { 37 printf("0\n"); 38 return 0; 39 } 40 flag = 1; 41 for(i = 1;i <= n&&flag;i ++) 42 { 43 for(j = i+1;j <= n&&flag;j ++) 44 { 45 if(gcd(p[i],p[j]) == 1) 46 { 47 v = p[i]*p[j] - 1 48 flag = 0; 49 } 50 } 51 } 52 dp[0] = 1; 53 for(i = 1;i <= n;i ++) 54 { 55 for(j = p[i];j <= v;j ++) 56 { 57 dp[j] += dp[j-p[i]]; 58 } 59 } 60 for(i = v;i >= 1;i --) 61 { 62 if(dp[i] == 0) break; 63 } 64 printf("%d\n",i); 65 return 0; 66 }