难度:中等
提示
一个魔法师有许多不同的咒语。
给你一个数组 power ,其中每个元素表示一个咒语的伤害值,可能会有多个咒语有相同的伤害值。
已知魔法师使用伤害值为 power[i] 的咒语时,他们就 不能 使用伤害为 power[i] - 2 ,power[i] - 1 ,power[i] + 1 或者 power[i] + 2 的咒语。
每个咒语最多只能被使用 一次 。
请你返回这个魔法师可以达到的伤害值之和的 最大值 。
示例 1:
输入:power = [1,1,3,4]
输出:6
解释:
可以使用咒语 0,1,3,伤害值分别为 1,1,4,总伤害值为 6 。
示例 2:
输入:power = [7,1,6,6]
输出:13
解释:
可以使用咒语 1,2,3,伤害值分别为 1,6,6,总伤害值为 13 。
提示:
1 <= power.length <= 10^51 <= power[i] <= 10^9
代码
#include <stdlib.h>
#include <stdio.h>
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
long long maximumTotalDamage(int* power, int powerSize) {
if (powerSize == 0) return 0;
// 对原数组排序以便统计
qsort(power, powerSize, sizeof(int), compare);
// 统计不同伤害值的总伤害
int* damage = (int*)malloc(powerSize * sizeof(int));
long long* valueList = (long long*)malloc(powerSize * sizeof(long long));
int count = 0; // 不同伤害值的数量
for (int i = 0; i < powerSize; i++) {
if (i == 0 || power[i] != power[i-1]) {
damage[count] = power[i];
valueList[count] = power[i];
count++;
} else {
valueList[count-1] += power[i];
}
}
if (count == 0) {
free(damage);
free(valueList);
return 0;
}
// 动态规划数组
long long* dp = (long long*)malloc(count * sizeof(long long));
long long* pre = (long long*)malloc(count * sizeof(long long));
int j = -1; // 指针,指向满足 damage[j] <= damage[i]-3 的最大下标
for (int i = 0; i < count; i++) {
// 移动指针 j
while (j + 1 < i && damage[j+1] <= damage[i] - 3) {
j++;
}
// 计算 dp[i]
if (j >= 0) {
dp[i] = valueList[i] + pre[j];
} else {
dp[i] = valueList[i];
}
// 更新 pre[i]
if (i == 0) {
pre[i] = dp[i];
} else {
pre[i] = (pre[i-1] > dp[i]) ? pre[i-1] : dp[i];
}
}
long long ans = pre[count-1];
// 释放内存
free(damage);
free(valueList);
free(dp);
free(pre);
return ans;
}
384

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



