博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P1734 最大约数和
阅读量:5917 次
发布时间:2019-06-19

本文共 1454 字,大约阅读时间需要 4 分钟。

线性筛+背包

讲道理这道题在线性筛后就让我们想到暴力的做法,毕竟写了\(n \leq 1000\)

其实你要用背包做的。

dp也很显然的,就用一维来表示和不超过\(i\)的最大的所谓约数和。

为什么是所谓的呢?你约数和是包括自己的。所以在这道题中你要自己把数字本身手工去掉。

当然不是叫你在线性筛的时候弄掉,在dp的时候抠掉即可。

线性筛不难的,就那么几种情况,手工推推式子就可以得到了。

讲道理这题还pj-

代码:

#include
#include
const int maxn = 1005, N = maxn - 5;bool notprime[maxn];int prime[maxn], tot;int ysh[maxn], mm[maxn];int dp[maxn];int n;void init(){ notprime[1] = true; ysh[1] = 1; mm[1] = 1; for(int i = 2; i <= N; i++) { if(!notprime[i]) { prime[++tot] = i; ysh[i] = mm[i] = i + 1; } for(int j = 1; j <= tot && i * prime[j] <= N; j++) { notprime[i * prime[j]] = true; if(i % prime[j]) { ysh[i * prime[j]] = ysh[i] * ysh[prime[j]]; mm[i * prime[j]] = prime[j] + 1; } else { ysh[i * prime[j]] = ysh[i] / mm[i] * (mm[i] * prime[j] + 1); mm[i * prime[j]] = mm[i] * prime[j] + 1; break; } } }}int main(){ init(); scanf("%d", &n); for(int i = 1; i <= n; i++) { dp[i] = ysh[i] - i; for(int j = 1; j < i; j++) { dp[i] = std::max(dp[i], dp[j] + ysh[i - j] - (i - j)); } } //for(int i = 1; i <= n; i++) printf("%d ", dp[i]); //printf("\n"); printf("%d\n", dp[n]); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9892823.html

你可能感兴趣的文章
Exchange 2013 CU17和office 365混合部署-添加域(一)
查看>>
英国的测绘与地理信息法规政策
查看>>
MYSQL性能查看(命中率,慢查询)
查看>>
自动输入sudo密码
查看>>
C#的Timer控件在Windows Service里面无效
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
Unable to execute dex: Multiple dex files define 的解决方法
查看>>
月薪一万的北漂可以过上什么样的生活?
查看>>
xp系统无法搜索
查看>>
创业公司如何在夹缝中求生存
查看>>
linux 删除文件后磁盘空间不释放的原因
查看>>
Yii2 使用 Beanstalk 队列
查看>>
为Cacti增加Monitor、Thold插件
查看>>
Google Apps 增加 DKIM 邮件签名验证来抵御垃圾邮件
查看>>
控件总结(四)
查看>>
hibernate sava方法和persisit方法
查看>>
史上最牛的五次******
查看>>
crash down
查看>>
FCKEditor2.6.6 配合 JavaWeb 的 使用步骤
查看>>