【问题标题】:Form subset of an array with special constraints形成具有特殊约束的数组的子集
【发布时间】:2017-11-04 05:31:13
【问题描述】:

我最近在一次编程比赛中遇到了这个问题: 我们必须与成员组成一个技能小队,使得没有一个成员的技能比小队中任何两个其他成员的技能总和更高。 给定n个成员的技能数组,找到具有上述约束的小队可能的最大技能总和。 我使用了一个贪心算法: - 对数组进行排序; - 使用三个指针并选择索引,使得前两个元素(最小)的总和小于所考虑子数组的最后一个(最大元素)。 - 还要继续移动索引以检查所有此类子数组并返回它们之间的最大总和。 但这通过了一半的案例,而其他案例则失败了。有人可以帮我解决我在这里缺少的东西吗?以下是我的程序:

//Author:: Satish Srinivas
#include<bits/stdc++.h>

using namespace std;

int solve(int arr[],int n)
{
    sort(arr,arr+n);

    int sum[n];
    sum[0]=arr[0];

    //precompute sums    
    for(int i=1;i<n;i++)
    {
        sum[i]=sum[i-1]+arr[i];

    }

    if(n<=2)
        return sum[n-1];

    int res=INT_MIN;

    for(int i=0;i<=n-3;i++)
    {
        int min=arr[i]+arr[i+1];

        int j=i+1;

        while(j<=n-2 && arr[j+1]<=min)
            j++;

        if(j>i+1)
        {
         if(i==0)
         {
            if(res < sum[j]-sum[0])
             res=sum[j]-sum[0];
         }
         else
         {
            if(res < sum[j]-sum[i-1])
             res=sum[j]-sum[i-1];
         }

        }

    }
  return res;
}

int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
/*
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
*/
int arr1[]={10,4,4,5,4};
int n1=sizeof(arr1)/sizeof(arr1[0]);
cout<<solve(arr1,n1)<<endl;

int arr2[]={25,60,1,5,3,35};
int n2=sizeof(arr2)/sizeof(arr2[0]);
cout<<solve(arr2,n2)<<endl;

return 0;
}
//output:
//13
//120

【问题讨论】:

    标签: arrays algorithm greedy


    【解决方案1】:

    一些看起来有点不对劲的地方:

    1. 如果 n 等于 2,则返回 INT_MIN,因为您的 for 循环永远不会执行

    2. 更一般地说,您似乎认为 2 人的团队无效

    3. 当 i 等于 0 时,您想通过将 i 到 j 的所有数字相加来计算分数,这等于 sum[j] 但您计算 res=sum[j]-sum[0 ]

    4. 当您对数组进行排序后,实际上不需要在每次迭代中重置 j(这仅在您因超时而失败时才重要)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-24
      • 1970-01-01
      • 2021-11-14
      • 2018-11-04
      • 2019-05-25
      相关资源
      最近更新 更多