欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总帖:AtCoder Beginner Contest竞赛题解 | 汇总
【题目来源】
洛谷:[AT_abc340_c ABC340C] Divide and Divide - 洛谷
【题目描述】
黑板上写有一个整数
N
N
N。
高桥君会不断重复以下一系列操作,直到黑板上所有大于等于
2
2
2 的整数都消失为止。
- 从黑板上写着的所有大于等于 2 2 2 的整数中任选一个,记为 x x x。
- 从黑板上擦去一个 x x x,然后在黑板上新写上两个整数 ⌊ x 2 ⌋ \left\lfloor \dfrac{x}{2} \right\rfloor ⌊2x⌋ 和 ⌈ x 2 ⌉ \left\lceil \dfrac{x}{2} \right\rceil ⌈2x⌉。
- 每进行一次上述操作,高桥君需要支付 x x x 日元。
这里, ⌊ a ⌋ \lfloor a \rfloor ⌊a⌋ 表示不超过 a a a 的最大整数, ⌈ a ⌉ \lceil a \rceil ⌈a⌉ 表示不小于 a a a 的最小整数。
当无法再进行操作时,高桥君支付的金额总和是多少?
另外,可以证明,无论操作顺序如何,高桥君支付的金额总和都是相同的。
【输入】
输入通过标准输入按以下格式给出。
N N N
【输出】
输出高桥君支付的金额总和。
【输入样例】
3
【输出样例】
5
【算法标签】
《洛谷 AT_abc340_c Divide and Divide》 #递推# #记忆化搜索#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
#define int long long // 使用长整型防止溢出
int n; // 输入的数字
int ans; // 最终结果(实际未使用)
map<int, int> mp; // 记忆化存储,避免重复计算
/**
* 递归计算将数字x分解为1的总代价
* @param x 当前要分解的数字
* @return 将x分解为1的总代价
*/
int dfs(int x)
{
// 递归终止条件:当x=1时,不需要分解,代价为0
if (x == 1)
{
return 0;
}
// 如果已经计算过x的结果,直接返回(记忆化搜索)
if (mp[x] != 0)
{
return mp[x];
}
int curr = x; // 当前分解的代价
int x1 = x / 2; // 分解为第一个部分
int x2 = (x + 1) / 2; // 分解为第二个部分
// 总代价 = 当前分解代价 + 分解x1的代价 + 分解x2的代价
int tot = curr + dfs(x1) + dfs(x2);
// 将结果存入记忆化数组
mp[x] = tot;
return tot;
}
signed main() // 使用signed代替int(因为定义了#define int long long)
{
// 输入要分解的数字
cin >> n;
// 调用递归函数计算总代价
cout << dfs(n) << endl;
return 0;
}
【运行结果】
3
5
611

被折叠的 条评论
为什么被折叠?



