欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总贴:学而思编程2025年CodeStars年度综合评估真题解析 | 汇总
【题目来源】
小猴编程:学而思编程CodeStars年度综合评估
【题目描述】
皮皮是一名忠实的游戏爱好者,最近他迷上了一款叫作《怪物猎人》的动作角色扮演游戏。游戏的内容很简单,只要不停地制造武器打怪就好了。
这个游戏一共有 N N N 个怪物,分别有着不同的等级。皮皮需要在 K K K 天内按顺序把它们都打败。每一天,皮皮要做的第一件事情就是打造一把武器,而武器也有对应的等级,如果武器的等级低于怪物,那么皮皮就打不过那个怪物,否则皮皮就能战胜它。
已知皮皮每天只会去一次武器铺,购买任意等级的武器,然后去打一整天的怪物。但是每用一个武器打败一个怪物后,就需要支付与武器等级同样的金币来修理武器,注意:即使是击杀最后一个怪物也需要修理武器。
现在皮皮已经知道了 N N N 个怪物的等级,他想知道自己最少需要花费多少枚金币,能在 K K K 天内击杀所有的怪物。
【输入】
输入第一行两个整数 N N N 和 K K K,表示有 N N N 个怪物,皮皮有 K K K 天时间打怪。
第二行 N N N 个整数,依次表示 1 ∼ N 1∼N 1∼N 号怪物的等级 T i T_i Ti。
【输出】
输出一个正整数,表示皮皮至少需要花费的金币数。
【输入样例】
6 3
6 9 8 2 3 2
【输出样例】
33
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 505; // 定义最大城市数量
// 变量定义:
// n: 城市数量
// k: 最大天数
// a[N]: 每个城市的战力值
// dp[N][N]: 动态规划数组,dp[r][i]表示前r个城市用i天击败的最小金币消耗
int n, k;
int a[N], dp[N][N];
int main()
{
// 输入城市数量n和最大天数k
cin >> n >> k;
// 输入每个城市的战力值
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
// 初始化DP数组为极大值
memset(dp, 0x3f, sizeof dp);
// 基础情况:0个城市0天消耗0金币
dp[0][0] = 0;
// 动态规划求解
for (int r = 1; r <= n; r++) // 枚举右边界
{
int mx = 0; // 记录当前区间的最大战力值
for (int l = r; l >= 1; l--) // 枚举左边界(注意这里要倒序枚举)
{
mx = max(mx, a[l]); // 更新区间最大战力值
// 枚举可能的天数
for (int i = 1; i <= min(r, k); i++)
{
// 状态转移方程:
// 前r个城市i天的最小消耗 = min(自身, 前l-1个城市i-1天的消耗 + 当前区间消耗)
dp[r][i] = min(dp[r][i], dp[l - 1][i - 1] + (r - l + 1) * mx);
}
}
}
// 寻找最优解(在所有可能天数中找最小值)
int ans = 1e9;
for (int i = 1; i <= k; i++)
{
ans = min(ans, dp[n][i]);
}
// 输出结果
cout << ans << endl;
return 0;
}
【运行结果】
6 3
6 9 8 2 3 2
33