翻转卡片以获得最大金额

时间:2014-07-25 20:28:25

标签: c++ algorithm

给定N张牌,如果第i张牌的正面有数字x,则背面会有-x,而且只能进行一次操作,只能连续顺序翻转任意数量的牌。

现在我们需要以卡片上面的数量总和最大的方式翻转卡片。

示例:如果N = 5且cards []为{-2,3,-1,-4,-2},那么这里的答案是8,因为我们可以翻转最后3张卡来获得配置{-2,3, 1,4,2}总和为8。

我的方法:

为每个第i个位置选择每种可能的方式作为起始位置并找到最大值。但是他们能解决这个问题吗?

我的代码:到目前为止还无法找到问题

#include<bits/stdc++.h>
using namespace std;
int solve(std::vector<int> const & numbers)
{
    int min_so_far  = numbers[0], min_ending_here = numbers[0];
    size_t begin = 0;
    size_t begin_temp = 0;
    size_t end = 0;
    for(size_t i = 1; i < numbers.size(); i++)
    {
            if(min_ending_here > 0)
            {
                    min_ending_here = numbers[i];
                    begin_temp = i;
            }
            else
            {
                    min_ending_here += numbers[i];
            }

            if(min_ending_here <= min_so_far )
            {
                    min_so_far  = min_ending_here;
                    begin = begin_temp;
                    end = i;
            }
    }
    int sum=0;
    for(int i=0;i<begin;i++){
        sum+=numbers[i];
    }
    for(int i=begin;i<=end;i++){
        sum-=numbers[i];
    }
    for(int i=end+1;i<numbers.size();i++){
        sum+=numbers[i];
    }
    return sum;

}
int main(){
int n;
cin>>n;
vector<int> arr;
for(int i=0;i<n;i++){
    int x;
    cin>>x;
    arr.push_back(x);
}

  cout<<solve(arr)<<"\n";
}

1 个答案:

答案 0 :(得分:8)

您唯一需要找到的是您可以用连续数字形成的最小总和,然后翻转它们。在你的例子中,最后三个数字加起来为-7,并且没有其他一组具有较低总和的连续数字,因此翻转它们就可以了。如果最小金额是非负数,那么您就不需要翻转它们。

现在,我上面描述的是一个众所周知的算法,它被称为Kadane's algorithm,它可以在O(n)中解决,请注意维基百科链接显示了如何最大限度地做到这一点,但是您可以轻松修改它以找到最小值。