寻找正整数数组的最大权重子序列?

发布于 2024-09-02 18:58:04 字数 1402 浏览 1 评论 0原文

我试图找到正整数数组的最大权重子序列 - 问题是最终子序列中不允许有相邻成员。

提出了完全相同的问题 这里,MarkusQ给出了一个递归解决方案,如下:

function Max_route(A)
if A's length = 1 
    A[0]
  else
    maximum of
      A[0]+Max_route(A[2...])
      Max_route[1...]

他提供了一个解释,但是任何人都可以帮助我理解他是如何扩展函数的吗?具体来说,他为什么

f[] :- [],0
f [x]     :- [x],x
f [a,b]   :- if a > b then [a],a else [b],b
f [a,b,t] :- 
    ft = f t
    fbt = f [b|t]
    if a + ft.sum > fbt.sum
        [a|ft.path],a+ft.sum
    else
      fbt

f[] 扩展为 [],0?另外他的解决方案如何考虑非相邻成员?

我有一些基于这个算法的 C++ 代码,如果有人想看的话我可以发布这些代码,但我就是无法理解它为什么会起作用。

==========对于任何感兴趣的人 - C++ 代码 ==============

我应该补充一点,整数数组将被视为循环列表,因此任何包含第一个元素的序列都不能包含最后一个元素。

int memo[55][55];

int solve(int s, int e)
{
    if( s>e ) return 0;
    int &ret=memo[s][e];
    if(ret!=-1)
    {
        return ret;
    }
    ret=max(solve(s+1,e), solve(s+2,e)+a[s]);
    return ret;
}

class Sequence
{
    public:
    int maxSequence(vector <int> s)
    {
            memset(memo,-1);
            int n = s.size();
            for(int i=0; i<n; i++)
                a[i]=s[i];
            return max(solve(0,n-2),solve(1,n-1));
        }
};

I'm tring to find the maximum weight subsequence of an array of positive integers - the catch is that no adjacent members are allowed in the final subsequence.

The exact same question was asked here, and a recursive solution was given by MarkusQ thus:

function Max_route(A)
if A's length = 1 
    A[0]
  else
    maximum of
      A[0]+Max_route(A[2...])
      Max_route[1...]

He provides an explanation, but can anyone help me understand how he has expanded the function? Specifically what does he mean by

f[] :- [],0
f [x]     :- [x],x
f [a,b]   :- if a > b then [a],a else [b],b
f [a,b,t] :- 
    ft = f t
    fbt = f [b|t]
    if a + ft.sum > fbt.sum
        [a|ft.path],a+ft.sum
    else
      fbt

Why does he expand f[] to [],0? Also how does his solution take into consideration non-adjacent members?

I have some C++ code that is based on this algorithm, which I can post if anyone wants to see it, but I just can't for the life of me fathom why it works.

==========For anyone who's interested - the C++ code ==============

I should add, that the array of integers is to be treated as a circular list, so any sequence containing the first element cannot contain the last.

int memo[55][55];

int solve(int s, int e)
{
    if( s>e ) return 0;
    int &ret=memo[s][e];
    if(ret!=-1)
    {
        return ret;
    }
    ret=max(solve(s+1,e), solve(s+2,e)+a[s]);
    return ret;
}

class Sequence
{
    public:
    int maxSequence(vector <int> s)
    {
            memset(memo,-1);
            int n = s.size();
            for(int i=0; i<n; i++)
                a[i]=s[i];
            return max(solve(0,n-2),solve(1,n-1));
        }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

探春 2024-09-09 18:58:04

我不太明白那个伪代码,所以如果这没有帮助,请发布 C++ 代码,我会尝试改进它。

我试图找到正整数数组的最大权重子序列 - 问题是最终子序列中不允许有相邻成员。

a 为正整数数组。令f[i] = 序列a[0..i] 的最大权重子序列的值

我们有:

f[0] = a[0],因为如果只有一个元素,我们就必须采用它。
f[1] = max(a[0], a[1]) 因为你没有相邻元素的限制,所以如果你有两个元素,你只能取其中之一。取最大的一个是有意义的。

现在,通常您会:

f[i > 1] = max(
           f[i - 2] + a[i] <= add a[i] to the largest subsequence of the sequence a[0..i - 2]. We cannot take a[0..i - 1] because otherwise we risk adding an adjacent element.
           f[i - 1] <= don't add the current element to the maximum of a[0..i - 2], instead take the maximum of a[0..i - 1], to which we cannot add a[i].
              )

我认为这种方式比您那里的方式更容易理解。这些方法是等效的,我只是发现对于这个特定问题来说更清晰,因为在这种情况下递归使事情变得更困难,并且伪代码无论哪种方式都可以更清晰。

I don't really understand that pseudocode, so post the C++ code if this isn't helpful and I'll try to improve it.

I'm tring to find the maximum weight subsequence of an array of positive integers - the catch is that no adjacent members are allowed in the final subsequence.

Let a be your array of positive ints. Let f[i] = value of the maximum weight subsequence of the sequence a[0..i].

We have:

f[0] = a[0] because if there's only one element, we have to take it.
f[1] = max(a[0], a[1]) because you have the no adjacent elements restriction, so if you have two elements, you can only take one of them. It makes sense to take the largest one.

Now, generally you have:

f[i > 1] = max(
           f[i - 2] + a[i] <= add a[i] to the largest subsequence of the sequence a[0..i - 2]. We cannot take a[0..i - 1] because otherwise we risk adding an adjacent element.
           f[i - 1] <= don't add the current element to the maximum of a[0..i - 2], instead take the maximum of a[0..i - 1], to which we cannot add a[i].
              )

I think this way is easier to understand than what you have there. The approaches are equivalent, I just find this clearer for this particular problem, since recursion makes things harder in this case and the pseudocode could be clearer either way.

蓬勃野心 2024-09-09 18:58:04

但你不明白什么?对我来说这似乎很清楚:

  • 我们将为给定序列的每个前缀构建最大子序列
  • 来​​计算长度 i 的前缀的最大子序列,我们考虑两种可能性:最后一个元素是,或者不在最大子序列中(显然没有其他可能性)。
  • 如果存在,我们考虑最后一个元素的值,加上前缀短两个元素的最大子序列的值(因为在这种情况下,我们知道最后一个元素不能出现在最大子序列中,因为 相邻元素规则)
  • 如果不是,我们取短一个元素的前缀的最大和的值(如果前缀的最后一个元素不在最大子序列中,则最大子序列必须等于这个和)前面的前缀)
  • 我们比较并取两个加号中的最大值

:您需要记住实际的子序列;您需要避免多余的函数调用,因此需要记忆。

为什么他将f[]扩展为[],0

因为返回值中的第一个表示当前最大子序列,第二个是它的值。空序列的最大子序列为空且值为零。

But what do you NOT understand? It seems quite clear for me:

  • we will build the maximal subsequence for every prefix of our given sequence
  • to calculate the maximal subsequence for prefix of length i, we consider two possibilities: Either the last element is, or isn't in the maximal subsequence (clearly there are no other possibilities).
  • if it is there, we consider the value of the last element, plus the value of maximal subsequence of the prefix two elements shorter (because in this case, we know the last element cannot be present in the maximal subsequence because of the adjacent elements rule)
  • if it isn't we take the value of maximal sum of prefix one element shorter (if the last element of the prefix is not in the maximal subsequence, the maximal subsequence has to be equal for this and the previous prefix)
  • we compare and take the maximum of the two

Plus: you need to remember actual subsequences; you need to avoid superfluous function invocations, hence the memoization.

Why does he expand f[] to [],0?

Because the first from the pair in return value means current maximal subsequence, and the second is its value. Maximal subsequence of an empty sequence is empty and has value zero.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文