算法提高 拿糖果
时间限制:1.0s 内存限制:256.0MB
问题描述
妈妈给小B买了N块糖!但是她不允许小B直接吃掉。
假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不大于根号下M的质因数。这时,妈妈就会在小B拿了P块糖以后再从糖堆里拿走P块糖。然后小B就可以接着拿糖。
现在小B希望知道最多可以拿多少糖。
输入格式
一个整数N
输出格式
最多可以拿多少糖
样例输入
15
样例输出
6
数据规模和约定
N <= 100000
分析:开始没有仔细审题,总想用简单贪心解决。后来仔细看题发现很难贪心写,因为最终的最大值与每一轮的拿取的糖果数P实际上没有绝对的关系。改用dp解决,从1开始,用dp数组存储每一个不大于N的数对应的最大输出。最后输出dp[N]即可。
代码:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int isPrime[1000001] = { 0 };
void initPrime() {
fill(isPrime, isPrime + 1000001, 1);
isPrime[0] = isPrime[1] = 0;
for (int i = 4; i < 1000001; i += 2) {
isPrime[i] = 0;
}
for (int i = 3; i < 1000001; i += 2) {
for (int j = i * 3; j < 1000001; j += i) {
isPrime[j] = 0;
}
}
}
int main() {
int dp[1000001] = { 0 };
initPrime();
int N;
cin >> N;
for (int i = 1; i <= N; i++) {
for (int j = sqrt(i); j >= 2; j--) {
if (i % j == 0 && isPrime[j] == 1) {
dp[i] = max(j + dp[i - 2 * j], dp[i]);
}
}
}
cout << dp[N] << endl;
return 0;
}