拿糖果(动态规划)
题目描述妈妈给小B买了N块糖!但是她不允许小B直接吃掉。
假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不大于根号下M的质因数。这时,妈妈就会在小B拿了P块糖以后再从糖堆里拿走P块糖。然后小B就可以接着拿糖。
现在小B希望知道最多可以拿多少糖。输入一个整数N输出最多可以拿多少糖
样例输入15
样例输出6
此题有层层叠加的思想方法,我们分析买了一块糖小B最多可以拿多少,买了两块糖小B最多可以拿多少,一直到妈妈买了N块糖小B最多可以拿多少…
我们用dp[i]表示妈妈买了i块糖,小B最多可以拿多少。
计算dp[i],我们需要枚举j个(小于等于sqrt(i)且为i的质因数)所有可行方案,并且·取得最大值。那么dp[i]=max(dp[i],dp[i-2*j]+j)~~~~~这里dp[i-2j]是假设小B拿走了j块糖剩下dp[i-2j] (妈妈也拿走)块糖的最佳方案(有点类似于把前面记录过的最优方案数拿来选择当下的最佳方案)
废话不多说上代码
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e5+10;
int dp[N];
int main()
{
int n;
cin>>n;
dp[1]=1;
for(int i=1;i<=n;i++)
{
for(int j=2;j<=sqrt(i);j++)
{
if(i%j==0)
{
dp[i]=max(dp[i],dp[i-2*j]+j);
}
}
}
cout<<dp[n];
}