![](https://i-blog.csdnimg.cn/blog_migrate/535279ee81079b59dac724bd653fa3e7.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c7171c5c57ad8b8f88f140d8502e259d.png)
递归
#include <iostream>
using namespace std;
const int N = 10000010;
typedef long long LL;
LL n, x, y;
LL dfs(int u)//从n减到0
{
if (u == 1) return x;//前两行是递归边界
if (u == 2) return x + min(x, y);//可以先除再减,也可以减两次
if (u % 2 == 0) //偶数(除2、减2)
return dfs(u / 2) + min(y, x * u / 2);
else //奇数(加1、减1)
return x + min(dfs(u - 1), dfs(u + 1));
}
int main()
{
scanf("%lld%lld%lld", &n, &x, &y);
cout << dfs(n) << endl;
return 0;
}
dp
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 10000010;
int n;
int x, y;
LL f[N];
int main()
{
scanf("%d%d%d", &n, &x, &y);
memset(f, 0x3f, sizeof f);
f[0] = 0;
for (int i = 1; i <= n; i ++ )
if (i % 2)
f[i] = min(f[(i + 1) / 2] + x + y, f[i - 1] + x);
else
f[i] = min(f[i / 2] + y, f[i - 1] + x);
printf("%lld\n", f[n]);
}