
Sloution
预处理 小于s的每个数的 约数和
方案1: 复杂度 nnn \sqrt{n}nn
void init(){
a[1] = 0;
_for(i,2,s+1){
ll sum = 1;
for (int j = 2; j <= i / j;j++){
if(j * (i/j) == i){
sum += j;
if(j!=i/j)
sum += i / j;
}
}
a[i] = sum;
}
}
方案2:
筛法改:O(nlog n)
void prime(){
for (int i=1;i<=n;i++)
for (int j=i*2;j<=n;j+=i)a[j]+=i;
}
预处理完后就是一个01背包
const int N = 1100;
ll a[N];
ll f[N];
int s;
void init(){
a[1] = 0;
_for(i,2,s+1){
ll sum = 1;
for (int j = 2; j <= i / j;j++){
if(j * (i/j) == i){
sum += j;
if(j!=i/j)
sum += i / j;
}
}
a[i] = sum;
}
}
int main()
{
//freopen("in.txt", "r", stdin);
cin >> s;
init();
_for(i,1,s+1){
for_(j, s, i)
f[j] = max(f[j], f[j - i] + a[i]);
}
cout << f[s];
}
本文探讨了两种高效算法:方案1通过迭代计算每个数的约数和,达到O(n√n)复杂度;方案2采用筛法改进,实现O(n log n)效率。后续部分介绍了如何将预处理结果应用于01背包问题。

617

被折叠的 条评论
为什么被折叠?



