【题目大意】
选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。
输入一个正整数S。
输出最大的约数之和。
样例输入 Sample Input
11
样例输出 Sample Output
9
样例说明
取数字4和6,可以得到最大值(1+2)+(1+2+3)=9。数据规模对于30%的数据,S≤10;
对于100%的数据,S≤1000。
【思路】
水题,普通的01背包问题,唯一需要注意的一点是,1的所有约数之和是0!我一开始就因为1没有单独判断而导致了错误。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 const int MAXN=1000+50; 7 int s; 8 int w[MAXN],f[MAXN]; 9 10 int main() 11 { 12 freopen("mr359.in7","r",stdin); 13 freopen("mr359.ou7","w",stdout); 14 scanf("%d",&s); 15 memset(w,0,sizeof(w)); 16 w[1]=0; 17 for (int i=2;i<=s;i++) 18 { 19 for (int j=1;j<=sqrt(i);j++) 20 if (i%j==0) 21 { 22 w[i]+=j; 23 if (j*j!=i && j!=1) w[i]+=i/j; 24 } 25 } 26 27 f[0]=0; 28 for (int j=1;j<=s;j++) f[j]=-0x7fffffff; 29 for (int i=0;i<=s;i++) 30 for (int j=s;j>=i;j--) 31 { 32 f[j]=max(f[j],f[j-i]+w[i]); 33 } 34 cout<<f[s]<<endl; 35 return 0; 36 }