需要更好的算法来为Sphere Online Judge的“FOODIES - ChickenLove”挑战

时间:2016-12-18 23:20:19

标签: algorithm

我正在尝试解决Sphere Online Judge's "FOODIES - ChickenLove" problem。在这个问题中,有 n 形式{1,2,..., A1 },{1,2,..., A2 },...,{1,2,..., An }。 (输入只包含整数 A1 A2 ,... An ;隐含了其他元素。)问题的目标是,对于给定的 m ,通过从这些集合中选择 m 不同的元素来找到可以获得的最大总和。

例如,给定此输入:

  • A1 = 3 (意味着第一组是{1,2,3})
  • A2 = 5 (意味着第二组是{1,2,3,4,5})
  • A3 = 4 (意味着第三组是{1,2,3,4})
  • m = 3 (意味着我们需要从这些集合中选择三个元素)

期望的结果是4 + 4 + 5 = 13

目前我正在使用优先级队列来解决这个问题,但是我遇到了“超时”错误(这意味着我的解决方案需要太长时间)。如何优化我的解决方案?有更好的方法吗?

我当前的方法

#include <bits/stdc++.h>
using namespace std;

int main() 
{
int t;
scanf("%d",&t);
while(t--)
{
    int n,k,x;
    long long c=0;
    scanf("%d",&n);
    priority_queue<int> pq;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&x);
        pq.push(x);
    }
    scanf("%d",&k);
    for(int i=1;i<=k;i++)
    {
        int p=pq.top();
        c+=p;
        pq.push(p-1);
        pq.pop();

    }
   printf("%lld\n",c);
}
return 0;
}  

1 个答案:

答案 0 :(得分:1)

您的时间限制已超出,因为最大M <= 10^10,您的代码的时间复杂度为O(N + M log N)

这个问题的约束是1 <= A[i] <= 100000,所以你可以计算所有集合中x的数量(在我的代码中:值为c [x])。

因此,您只需处理1 <= i <= N的查询。 (c [i]的初始值= 0)

  • 将值1添加到值c [1],c [2],c [3],...,c [A [i]]。

您可以使用O(M)的幼稚算法和O(N)的累加和算法进行处理。

如果算上c[1], c[2], ..., c[max(A[1], A[2],..., A[N])],就可以像我的代码一样:

#include <bits/stdc++.h>
using namespace std;
int T, N; long long M;
int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &N);
        vector<int> A(N);
        for(int i = 0; i < N; i++) scanf("%d", &A[i]);
        scanf("%lld", &M);
        int z = *max_element(A.begin(), A.end());
        vector<int> c(z + 2), s(z + 2);
        for(int i = 0; i < N; i++) s[1]++, s[A[i] + 1]--;
        for(int i = 1; i <= z; i++) c[i] = c[i - 1] + s[i];
        long long ret = 0;
        for(int i = z; i >= 1; i--) {
            if(M <= c[i]) {
                ret += 1LL * M * i; M = 0;
                break;
            }
            ret += 1LL * c[i] * i; M -= c[i];
        }
        printf("%lld\n", ret);
    }
    return 0;
}

整体时间复杂度为O(N + max(A[1], A[2],..., A[N])) 我提交给SPOJ,我得到了AC(0.20秒)!