1 条题解
-
0
自动搬运
来自洛谷,原作者为

引领天下
用6年时间,讲好一个笑话。搬运于
2025-08-24 21:28:27,当前版本为作者最后更新于2017-07-29 17:09:50,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
其实这题是个背包(我用暴力只得了20分)
S就是背包容量V,i就是重量,i的因子和就是价值。
这样一讲公式就出来了吧!
公式:
i为第一个数,j为第二个数,a[k]为k的因子和 dp[i]=max(dp[i-j]+a[j],dp[i]);这个公式我想大家都能很方便地推出来。
接下来我要讲一讲本题一个很重要的优化,楼下们的代码中都或多或少的有,只是他们没有解释(大佬哪有时间解释)
于是,我这个蒟蒻就来解释一下吧!
本题一个很重要的优化就是:预处理!
void prime(){ for (int i=1;i<=n;i++) for (int j=i*2;j<=n;j+=i)a[j]+=i; }看到这段预处理代码,有没有想到筛法?
没错,就是从筛法改过来的!
这个是筛法↓
bool s[10000]={1,1};//0和1啥都不是,定1! int a[10000],ps;//a数组存最后的质数,ps为这个数组的下标 //全局数组初值全为0 inline void $(){//不要在意函数名,这只是个筛法函数 //财迷心窍的我 for (int j=2;j<10000;j++)//暴力!汗! if (!s[j]){//s[j]=0,表明j不是合数(合数为1) a[ps++]=j;//纪录下j这个质数,下一个 for (int k=j*2;k<10000;k+=j)//k=j*2省一个判断,每次+j,保证是j的倍数 s[k]=1;//既然是j的倍数,那一定是合数,标记! } }我将筛法改了一下,就有了这个函数。
因为是要因子和,而合数因子也算在里面,所以不用判断质数,那个bool数组自然就不要了
j=i*2表示j初值为i的2倍,j+=i则保证j是i的倍数,就加上i这个因子
开始预处理到n,打好了一个动态表,接下来dp时就可以直接引用了
筛法的应用还有很多,所以,随机应变,打动态表可以节省很多时间哦!
代码我就不贴了,希望大家能明白预处理的重要性
- 1
信息
- ID
- 711
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者