求助c++解法

jamjam9988 2024-01-15 17:47:57

题目描述

在冒险岛这款游戏中,有一个著名的山洞副本,里面有丰富的宝藏,引来了许多勇者前来挑战。
不幸的是,山洞中有 N 个怪物,第 i 个怪物的防御力为 A_i , 奖励值为 B_i , M 个勇者依次前来挑战。
假设一位勇者初始的战斗力为 X , 当你的战斗力大于怪物的防御力 A_i 时,你才可以击败它,并且获得奖励值 B_i 的战斗力提升。
幸运的是,每位勇者都深知自己的战斗力不一定充足,所以他会在进入山洞战斗前进行训练,依次来提升他的战斗力,并且勇者都是很聪明的,每位勇者都可以选择任意顺序来击败怪物,一个怪物只能被击败一次。
具体来说:假设训练总天数为 n , 勇者第 i 天的战斗力提升为 min(i,n-i+1);
因为勇者都希望自己能尽快穿越山洞,请你帮助每位勇者计算他最少训练多少天可以击败所有怪物?
你可以认为不同的勇者之间是互相独立的,副本中的怪物会重新恢复状态。

输入

第一行 1 个正整数 N , 表示怪物的数量;
第二行 N 个正整数 A_1, A_2,……, A_N。即每个怪物的防御力;
第三行 N 个正整数 B_1, B_2, ……, B_N。即每个怪物的奖励值;
第四行 1 个正整数 M , 表示有 M 个勇者前来挑战;
接下来 M 行,每行输入 1 个正整数 X , 表示这名勇者的初始战斗力值;

输出

输出 1 行 M 个整数,表示每名勇者最少需要训练的天数。

样例输入 复制

3
4 8 2
1 1 1
3
1
5
4

样例输出 复制

4 2 3

提示

【样例解释】
一共有 3 位勇者前来挑战。
*   第一位勇者锻炼 4 天 , 攻击力为 1+1+2+2+1=7  ,然后可以击败所有怪物
*   第二位勇者锻炼 2 天 , 攻击力为 5+1+1=7  ,可以击败所有怪物
*   第三位勇者锻炼 3 天 , 攻击力为 4+1+2+1=8  ,可以击败所有怪物

【数据范围】
*   对于 30% 的数据,1≤ N , M ≤ 100 ,  1≤ X,A_i,B_i≤100
*   对于 100% 的数据,1≤ N,M≤ 2*10^5 , 1≤ X,A_i,B_i≤ 10^9

 

刚开始学,求个简单的算法TAT

...全文
463 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

这是一道动态规划的问题。我们可以使用一个二维数组 dp[i][j] 来表示勇者 i 在第 j 天击败所有怪物的最小天数。其中 i 表示勇者的编号,j 表示天数。

根据题目的要求,勇者在每一天的战斗力提升是 min(i, n-i+1),所以在计算 dp[i][j] 时,我们需要考虑两种情况:

  1. 勇者在第 j 天击败怪物 a[j],则他的战斗力为 min(j, n-j+1) + a[j],并且他还需要在剩下的天数中击败剩余的怪物。所以我们可以得到状态转移方程:
    dp[i][j] = 1 + min(dp[i][j], dp[i][j-1]) + (n-j+1) * (a[j]/max(a))
  2. 勇者在第 j 天没有击败怪物 a[j],则他的战斗力仍然为 min(i, n-i+1),并且他还需要在剩下的天数中击败剩余的怪物。所以我们可以得到状态转移方程:
    dp[i][j] = min(dp[i][j], dp[i][j-1])

最后,我们可以输出 dp[M][N] 的值即可。

以下是具体的实现代码:

N, M = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

dp = [[0] * N for _ in range(M)]
for j in range(N):
    dp[0][j] = 1 + (N - j) * (a[j] / max(a)) if a[j] > 0 else 0
for i in range(1, M):
    for j in range(N):
        dp[i][j] = min(dp[i][j], dp[i][j-1]) if j > 0 else dp[i][j-1]
        if a[j] > 0:
            dp[i][j] = min(dp[i][j], 1 + dp[i][j-1] + (N - j) * (a[j] / max(a)))
print(" ".join(map(str, dp[M-1])))

其中,我们首先读入 N、M、a、b 的值,然后初始化 dp 数组。接着,我们遍历每一天和每一位勇者,根据状态转移方程计算 dp 数组的值。最后,我们输出 dp[M-1] 的值即可。

299,484

社区成员

发帖
与我相关
我的任务
社区描述
C++领域交流社区,旨在为大家提供一个文明交流,互相探讨兴趣爱好的环境,欢迎各位大佬加入。
c++ 个人社区 广东省·深圳市
社区管理员
  • 桃花键神
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧