Beef McNuggets USACO 4.1(数论公约数问题+背包阵亡)

4章第一题就跪..

数论先不说,先说背包,大概意思简化为,n个数,无限取用,给你个组合上限,找到最大的不能组合的数。开始还是有点迷惑,没看懂,

后来一想貌似就是完全背包啊...

还没有完全背包的那个例子复杂...

再说数论,一个开始题目里用到这样的例子, abc 3个数,ab的最大公约=m, mc的最大公约=1,证abc最大公约数=1

其实这题可以转为证明ab的最大公约数是否一定能整出其他公约数,假设abc存在非0公约数d,那么d<m且是ab公约,可知d一定不能被m整出

若d能被m整出,又c能整出d,那么mc的最大公约!=1,条件冲突!!!

所以这里转为证明 ab的最大公约数是否一定能整出其他公约数。

ab 最大公约设为m,较小的一个公约为n

设x=a/m,y=b/m,可知gcd(x,y)=1;

又mx ,my能整出n,假设m不能整出n

那么mx,my除n时有一部分一定是要被x和y除掉的,且相同。

那么x,y有公约数,这里又冲突,所以反证得出m一定整除n。

这题还有些东西,下次整理下,先贴个仿照的代码过了再说

gcd(int a,int b)

{

   if(a==0)

    return b;

  return gcd(b%a,a);

}

 1 /*
 2 
 3 ID: hubiao cave
 4 
 5 PROG: nuggets
 6 
 7 LANG: C++
 8 
 9 */
10 
11 
12 
13 
14 #include<iostream>
15 #include<fstream>
16 #include<cstring>
17 #include<algorithm>
18 
19 using namespace std;
20 
21 
22 int gcd(int,int);
23 
24 int main()
25 
26 {
27 
28 
29     ifstream fin("nuggets.in");
30     ofstream fout("nuggets.out");
31     int buf[11],n;
32     fin>>n;
33     for(int i=0;i<n;i++)
34         fin>>buf[i];
35     sort(buf,buf+n);
36 
37     int t=buf[0];
38     for(int i=1;i<n;i++)
39     {
40         t=gcd(t,buf[i]);
41         if(t==1)
42             break;
43     }
44     
45     if(t!=1)
46     {
47         fout<<0<<endl;
48         return 0;
49     }
50 
51     bool b[1000000];
52     memset(b,false,sizeof(b));
53     b[0]=true;
54 
55     int sumv=buf[n-2]*buf[n-1]*gcd(buf[n-2],buf[n-1]);
56     int i,j;
57 
58     for(i=0;i<n;i++)
59     {
60         for(j=buf[i];j<=sumv;j++)
61         {
62             if(b[j-buf[i]])
63                 b[j]=true;
64         }
65     }
66 
67     for( i=sumv;i>0;i--)
68     {
69         if(b[i]==false)
70         {
71             break;
72         }
73     }
74     
75     fout<<i<<endl;
76     
77     return 0;
78 
79 
80 }
81 int gcd(int A,int B)
82 {
83     if(A==0)
84         return B;
85     return gcd(B%A,A);
86 }
原文地址:https://www.cnblogs.com/cavehubiao/p/3387025.html