作者:小迅
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目
示例
思路
题意 -> 给定两个数组 scores 和 ages,其中每组 scores[i] 和 ages[i] 表示第 i 名球员的分数和年龄。按 年龄较小球员的分数 严格不大于 一名年龄较大的球员 要求 返回分数数组和最大值
由于两个数组中的元素具有强相关,而且还无序,所有第一步肯定是要将两个数组对应的元素进行合并升序排列,那么合并之后的数组有年龄和分数,按哪一个升序呢?都可以的,本题使用的是按年龄,官方是按分数。正好可以相互对比
将数组元素合并排序之后,有两种方法求其最大和:
递归回溯
按照题目要求规划选择的方案,由于已经对数组元素进行排序,所有当前元素能不能选只取决于上一个选择的元素。那么哪些情况当前元素可选呢?
当前元素年龄等于上一个元素年龄
当前元素分数不小于上一个元素分数(年龄保证了升序)
最后保存最大元素和即可
动态规划
上述递归中,我们是先确定了选择的起点,然后慢慢淘汰起点位置到结束位置(结束位置肯定选择在数组末尾-贪心) 中 不符合题目要求的元素,最后保存有效元素之和。但是这种方法会导致很多重复计算。
然而,当前位置的最大元素和肯定和上一个元素有关系,所以定义dp数组,其中dp[i]的含义为当前位置最大的有效元素之和 那么转移方程为 dp[i] = dp[j] + 当前位置的分数,其中 dp[j] 为当前位置之前 能满足题意要求的 dp 中的最大值 递推方向为从头到尾
代码注释超级详细
代码
typedef struct data{
int score;
int age;
}data;//合并结构体
int cmp(const void *a, const void *b)
{//排序子函数
data *_a = (data *)a;
data *_b = (data *)b;
return _a->age == _b->age ? _a->score - _b->score : _a->age - _b->age;
}
#define MAX(a, b) ((a) > (b) ? (a) : (b))
/*递归回溯法
int max = 0;
void dfs(data *ans, int ansSize, int index, int sum)
{
int i = 0;
for (i = index + 1; i < ansSize; ++i) {//枚举下一个有效位置
if (ans[i].age == ans[index].age || ans[i].score >= ans[index].score) {//返回题意要求的位置
dfs(ans, ansSize, i, sum+ans[i].score);
}
}
if (max < sum) {//保存最大值
max = sum;
}
return;
}*/
int bestTeamScore(int* scores, int scoresSize, int* ages, int agesSize){
data ans[scoresSize];
for (int i = 0; i < scoresSize; ++i) {//合并
ans[i].score = scores[i];
ans[i].age = ages[i];
}
qsort(ans, scoresSize, sizeof(ans[0]), cmp);//排序
/*递归回溯法
max = 0;
for (int i = 0; i < scoresSize; ++i) {//枚举每一个起始位置
dfs(ans, scoresSize, i, ans[i].score);
}*/
int dp[scoresSize];
memset(dp, 0, sizeof(dp));//初始化dp
int max = 0;
for (int i = 0; i < scoresSize; ++i) {//更新dp数组
for (int j = i-1; j >= 0; --j) {//取当前位置之前的最大元素
if (ans[i].age == ans[j].age || ans[i].score >= ans[j].score)//取能取的元素
dp[i] = MAX(dp[i], dp[j]);
}
dp[i] += ans[i].score;
max = MAX(max, dp[i]);//保存最大值
}
return max;
}
作者:小迅
链接:https://leetcode.cn/problems/best-team-with-no-conflicts/solutions/2183444/dong-tai-gui-hua-zhu-shi-chao-ji-xiang-x-9tlb/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。