如何通过动态规划方法解决这个问题?
How to solve this problem through dynamic programming approach?
我正在解决数组上一个非常基本的问题。问题陈述是这样的:
SIS已经开设了一个篮球场,所以Demid决定举行一次篮球锻炼会。 2⋅n学生来到Demid的锻炼课程,他将他们排成两排相同大小的排(每排正好有n个人)。学生在每行中按从左到右的顺序从 1 到 n 编号。
现在德米德想选择一支球队打篮球。他会从左到右选择球员,每个被选中的球员的指数(不包括第一个被抽取的)将严格大于之前选择的球员的指数。为了避免优先选择其中一行,Demid 选择学生的方式是没有连续选择的学生属于同一行。第一个学生可以在所有2n名学生中选择(没有额外的限制),一个团队可以由任意数量的学生组成。
德米德认为,为了组成一个完美的团队,他应该以这样一种方式选择学生,即所有被选中的学生的总身高都是尽可能高的。帮助Demid找到他可以选择的团队中球员的最大可能总身高。
例如,如果输入是:(第一行包含 n 的值,接下来的 2 行包含学生的身高)
5
9 3 5 7 3
5 8 1 4 5
我的方法是:
#These are global variables and functions.
int arr1[n],arr2[n],sum=0,max=0;
void func1(i)
{
if(i==n)
{
if(sum>max)
max=sum;
return;
}
sum+=arr1[i];
for(k=i+1;k<n;k++)
func2(k);
}
void func2(i)
{
if(i==n)
{
if(sum>max)
max=sum;
return;
}
sum+=arr2[i];
for(k=i+1;k<n;k++)
func1(k);
}
#Caller module. In main
for(i=0;i<n;i++)
{
sum=0;
func1(i);
}
这是我基于逻辑推理的算法。我还没有编码,稍后会编码。因此,请随时指出代码中的任何逻辑错误。
我知道这可以使用动态编程方法轻松解决,而这种算法并不完全是这样。在这种情况下,函数将是什么样子?
据我所知,该算法的问题是我需要全局声明arr1
和arr2
,而我知道 main 函数中 n 的值。
动态编程在这里非常简单。我们有两个选择:从 A 中选择或跳过,从 B 中选择或跳过。我们自下而上的重复可能如下所示:
// Choose from A or skip
m[i][0] = max(A[i] + m[i - 1][1], m[i - 1][0])
// Choose from B or skip
m[i][1] = max(B[i] + m[i - 1][0], m[i - 1][1])
JavaScript 代码:
function f(A, B){
let m = new Array(A.length + 1)
for (let i=0; i<=A.length; i++)
// [a or skip, b or skip]
m[i] = [0, 0]
for (let i=1; i<=A.length; i++){
// Choose from A or skip
m[i][0] = Math.max(
A[i-1] + m[i - 1][1], m[i - 1][0])
// Choose from B or skip
m[i][1] = Math.max(
B[i-1] + m[i - 1][0], m[i - 1][1])
}
return Math.max(...m[A.length])
}
var a = [9, 3, 5, 7, 3]
var b = [5, 8, 1, 4, 5]
console.log(f(a, b))
我们可以定义 2 个函数 A 和 B。A(i) 是我们接下来从第一行选择索引为 i 或更大的球员可以获得的最大高度。 B(i) 与第二行相同。现在我们可以用 B 写 A,用 A 写 B。例如,A(i) 是所有索引 k 的最大值,通过从第一个集合中选择第 k 个元素加上我们从第二个集合中选择 k+1 或更高元素可以获得的最大值。B(i) 是对称的:
A(i) = max_{k=i..n} a[k] + B(k + 1); A(n) = a[n]
B(i) = max_{k=i..n} b[k] + A(k + 1); B(n) = b[n]
答案将是max(A(1),B(1))。
一个简单的方法是编写代码,因为它是用 2 个记忆函数编写的。我将使用 C 而不是 C++ 进行调整以使用基于 0 的索引。
#include <stdio.h>
#define N 5
int a[] = {9, 3, 5, 7, 3};
int b[] = {5, 8, 1, 4, 5};
int Avals[N], Bvals[N];
int B(int i);
int A(int i) {
if (i >= N) return 0;
if (Avals[i]) return Avals[i];
int max = 0;
for (int k = i; k < N; ++k) {
int val = a[k] + B(k + 1);
if (val > max) max = val;
}
return Avals[i] = max;
}
int B(int i) {
if (i >= N) return 0;
if (Bvals[i]) return Bvals[i];
int max = 0;
for (int k = i; k < N; ++k) {
int val = b[k] + A(k + 1);
if (val > max) max = val;
}
return Bvals[i] = max;
}
int main(void) {
int aMax = A(0);
int bMax = B(0);
printf("%dn", aMax > bMax ? aMax : bMax);
return 0;
}
我声称有一种方法可以用简单的循环替换记忆递归,这些循环以严格的索引顺序访问 Avals 和 Bvals 的元素,但我会让你弄清楚细节。这个结果将是更小、更快的代码。
- Project Euler问题4的错误解决方案
- 在java中解决这段代码时面临循环中的问题
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 难以理解某些人解决IOI问题的源代码
- 节俭并发:未解决的外部问题
- IpOpt拒绝解决不受约束的问题
- 如何解决这个超硬恒星的创造问题
- 循环无限运行C++解决骑士之旅问题
- 使用 bfs 解决连接组件问题时得到错误的答案
- 如何解决 Ninja c++ 构建和执行问题
- 无法在问题解决方案中执行输出逻辑
- 如何在不到O(N)的时间内解决这个问题?
- Arduino 用于语句错误。令牌之前的预期')' ';'。如何解决这个问题?
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 如何在不使用额外空间的情况下解决这个问题?
- 我无法在Visual Studio代码中使用CIN输入答案,它说输入您的年龄,但它说只读文本编辑器如何解决这个问题?
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 如何解决"no Qt platform plugin could be initialized"问题?
- 如何解决可能的唯一组合问题
- Windows上的模板有什么问题?解决方案是什么