P1734 最大约数和

1|0P1734 最大约数和

1|0基本思路

设状态方程F[i][j]为前i个数和为j时的最大约数和。

状态转移则是F[i][j] = max(F[i - 1][j], F[i - 1][j - i] + divisorSum(i)

即要么选i,要么不选。

1|0代码实现

WA一个点,TLE六个点

30ptsCode

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int S, ans = 0; int F[1010][1010]; int getCd(int n) { int sum = 0; for (int i = 1; i < n; i++) { if (n % i == 0) { sum += i; } } return sum; } int main() { cin >> S; for (int i = 1; i <= S; i++) { for (int j = 1; j <= i * (1 + i) / 2; j++) { if (j >= i) { F[i][j] = max(F[i][j], F[i - 1][j - i] + getCd(i)); if (j <= S) ans = max(ans, F[i][j]); } else { F[i][j] = F[i - 1][j]; } } } cout << ans; return 0; }

我觉得我思路是可行的,只好从代码实现上找问题。

首先for (int j = 1; j <= i * (1 + i) / 2; j++)是让我TLE的关键,我想改它。

然后我看了一眼题目,发现我犯了一个很严重的错误。S指的是选取若干个数的和,而不是指从1S中选若干个数!

所以我转移方程的第二维直接枚举到S即可。

解决了TLE问题。

然后就是第二个关键点,已经屡次犯错了,在写二维背包时,总是搞错F[i][j]=F[i1][j]的次序,从而导致很多情况下根本没让F[i1][j]参与状态转移。比如说该题又莫名写成了把F[i1][j]放在只有j<i时才进行转移。这显然是不对的。

正确的写法应是每一次都考虑F[i1][j],然后看情况考虑F[i1][jv[i]]+w[i].

for (int j = 1; j <= i * (1 + i) / 2; j++) { F[i][j] = F[i - 1][j]; if (j >= i) { F[i][j] = max(F[i][j], F[i - 1][j - i] + getCd(i)); } }

最终AC

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int S, ans = 0; int F[1010][1010]; int getCd(int n) { int sum = 0; for (int i = 1; i < n; i++) { if (n % i == 0) { sum += i; } } return sum; } int main() { cin >> S; for (int i = 1; i <= S; i++) { for (int j = 1; j <= S; j++) { F[i][j] = F[i - 1][j]; if (j >= i) { F[i][j] = max(F[i][j], F[i - 1][j - i] + getCd(i)); } } } cout << F[S][S]; return 0; }

优化空间

#include <iostream> #include <cstdio> #include <cstring> using namespace std; int S, ans = 0; int F[1010]; int getCd(int n) { int sum = 0; for (int i = 1; i < n; i++) { if (n % i == 0) { sum += i; } } return sum; } int main() { cin >> S; for (int i = 1; i <= S; i++) { for (int j = S; j >= i; j--) { F[j] = max(F[j], F[j - i] + getCd(i)); } } cout << F[S]; return 0; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17809374.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示