问题描述
妈妈给小明买了 N 块糖!但是她不允许小明直接吃掉。
假设当前有 N 块糖,小明每次可以拿 P 块糖,其中 P 是 N 的一个不大于根号下 N 的质因数。
这时,妈妈就会在小明拿了 P 块糖以后再从糖堆里拿走 P 块糖,然后小明就可以接着拿糖。
现在小明希望知道最多可以拿多少糖。
输入格式
一个整数 N
输出格式
最多可以拿多少糖
样例输入
15
样例输出
6
数据范围
N ≤ 105
题解一
记忆化搜索:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 100010;
int n;
int f[N];
bool judge(int x)
{
for (int i = 2; i <= x / i; i ++)
if(x % i == 0) return false;
return true;
}
int dfs(int x)
{
if(f[x] != -1) return f[x];
f[x] = 0;
for (int i = 2; i <= x / i; i ++)
if(judge(i) && x % i == 0)
f[x] = max(f[x], dfs(x - 2 * i) + i);
return f[x];
}
int main()
{
cin >> n;
memset(f, -1, sizeof f);
cout << dfs(n) << endl;
return 0;
}
题解二
动态规划:
#include <iostream>
using namespace std;
const int N = 100010;
int n;
int f[N];
bool judge(int x)
{
for (int i = 2; i <= x / i; i ++)
if(x % i == 0) return false;
return true;
}
int main()
{
cin >> n;
for (int i = 4; i <= n; i ++)
for (int j = 2; j <= i / j; j ++)
if(judge(j) && i % j == 0)
f[i] = max(f[i], f[i - 2 * j] + j);
cout << f[n] << endl;
return 0;
}
ps:哪有人叫小B的,这也太难听了,所以我决定当一次爸爸,替他改个名字😎