寻找有效的算法

时间:2014-11-29 14:33:05

标签: algorithm sorting time-complexity

    You are developing a smartphone app. You have a list of potential
    customers for your app. Each customer has a budget and will buy the app at
    your declared price if and only if the price is less than or equal to the
    customer's budget.
    You want to fix a price so that the revenue you earn from the app is
    maximized. Find this maximum possible revenue.
    For instance, suppose you have 4 potential customers and their budgets are
    30, 20, 53 and 14. In this case, the maximum revenue you can get is 60.
**Input format**
Line 1 : N, the total number of potential customers.
Lines 2 to N+1: Each line has the budget of a potential customer.
**Output format**
The output consists of a single integer, the maximum possible revenue you
can earn from selling your app.

  Also, upper bound on N is 5*(10^5) and upper bound on each customer's budget is 10^8.

这是我试图解决的问题。我的策略是对预算列表进行排序,然后将每个预算与序列中的位置索引相乘 - 然后打印结果序列的最大值。然而,这似乎是非常耗时的(至少在我实施它的方式 - 我已经附加了代码以供参考)。我的上限时间是2秒。任何人都可以帮我找到一个 更节省时间的算法(或者可能是一种更有效的方法来实现我的算法)?

这是我的解决方案:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

using namespace std;

long long max(long long[],long long);
void quickSortIterative(long long[],long long,long long);
long long partition(long long[],long long,long long);
void swap(long long*,long long*);

int main(){
    long long n,k=1;
    scanf("%lld",&n);
    if(n<1 || n > 5*((long long)pow(10,5))){
        exit(0);
    }
    long long budget[n],aux[n];
    for(long long i=0;i<n;i++){
        scanf("%lld",&budget[i]);
        if(budget[i]<1 || budget[i] > (long long)pow(10,8)){
             exit(0);
        }
    }
    quickSortIterative(budget,0,n-1);
    for(long long j=n-1;j>=0;j--){
        aux[j] = budget[j]*k;
        k++;
    }
    cout<<max(aux,n);
    return 0;
}

long long partition (long long arr[], long long l, long long h){
    long long x = arr[h];
    long long i = (l - 1);

    for (long long j = l; j <= h- 1; j++)
    {
        if (arr[j] <= x)
        {
            i++;
            swap (&arr[i], &arr[j]);
        }
    }
    swap (&arr[i + 1], &arr[h]);
    return (i + 1);
}

void swap ( long long* a, long long* b ){
    long long t = *a;
    *a = *b;
    *b = t;
}

void quickSortIterative(long long arr[], long long l, long long h){
    long long stack[ h - l + 1 ];
    long long top = -1;
    stack[ ++top ] = l;
    stack[ ++top ] = h;
    while ( top >= 0 ){

        h = stack[ top-- ];
        l = stack[ top-- ];
        long long p = partition( arr, l, h );
        if ( p-1 > l ){
            stack[ ++top ] = l;
            stack[ ++top ] = p - 1;
        }
        if ( p+1 < h ){
            stack[ ++top ] = p + 1;
            stack[ ++top ] = h;
        }
    }
} 

long long max(long long arr[],long long length){
    long long max = arr[0];
    for(long long i=1;i<length;i++){
        if(arr[i]>max){
            max=arr[i];
        }
    }
    return max;
}

7 个答案:

答案 0 :(得分:3)

Quicksort对于某些序列可能需要O(n ^ 2)时间(通常已经排序的序列很糟糕)。

我建议您尝试使用具有保证O(nlogn)性能的排序方法(例如,heapsort或mergesort)。或者,您可能会发现使用标准库中的排序例程将提供比您的版本更好的性能。

答案 1 :(得分:1)

您可以在C中使用qsort或在C ++中使用std :: sort,这很可能比您自己的代码更快。

另外,如果差值h-l很大,你的“堆栈”数组会给你带来麻烦。

答案 2 :(得分:1)

我使用过C ++的STL库函数sort()。它的时间复杂度是O(nlogn)。在这里,您只需要对给定的数组进行排序,并从给定解决方案的最大值到最小值进行检查。排序后是O(n)。

我的代码清除了所有测试用例:

#include <algorithm>
#include <stdio.h>
#include <cmath>
#include <iostream>

using namespace std;

int main(){
     long long n, a[1000000], max;
     int i, j;
     cin>>n;

     for(i = 0; i < n; i++){
        cin>>a[i];
     }

     sort(a, a + n);
     max  = a[n - 1];
     for(i = n - 2; i >= 0; i--){
         //printf("%lld ", a[i]);
        if(max < (a[i] * (n - i)))
            max = a[i] * (n - i);
     }

     cout<<max<<endl;
     return 0;
} 

答案 3 :(得分:0)

通过所有测试用例

n=int(input())
r=[]
for _ in range(n):
    m=int(input())
    r.append(m)
m=[]
r.sort()
l=len(r)
for i in range(l):
    m.append((l-i)*r[i])

print(max(m))

答案 4 :(得分:0)

以下解决方案采用C编程语言。

方法是:

  1. 输入客户数量。
  2. 输入客户预算。
  3. 排序预算。
  4. 分配收入= 0
  5. 遍历预算并将特定预算与剩余预算值相乘。
  6. 如果以前的收入<新的收入。将新收入分配给收入变量。

代码如下:

#include <stdio.h>

int main(void) {
int i,j,noOfCustomer;

scanf("%d",&noOfCustomer);
long long int budgetOfCustomer[noOfCustomer],maximumRevenue=0;

for(i=0;i<noOfCustomer;i++)
{
    scanf("%Ld",&budgetOfCustomer[i]);
}

for(i=0;i<noOfCustomer;i++)
{
    for(j=i+1;j<noOfCustomer;j++)
    {
        if(budgetOfCustomer[i]>budgetOfCustomer[j])
        {
           budgetOfCustomer[i]=budgetOfCustomer[i] + budgetOfCustomer[j];
           budgetOfCustomer[j]=budgetOfCustomer[i] - budgetOfCustomer[j];
           budgetOfCustomer[i]=budgetOfCustomer[i] - budgetOfCustomer[j];    
        }
       
    }
}


for(i=0;i<noOfCustomer;i++)
{
    budgetOfCustomer[i]=budgetOfCustomer[i]*(noOfCustomer-i);
}

for(i=0;i<noOfCustomer;i++)
{
    if(maximumRevenue<budgetOfCustomer[i])
    maximumRevenue=budgetOfCustomer[i];
}
printf("%Ld\n",maximumRevenue);

return 0;
}

答案 5 :(得分:0)

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

int main() {
// your code goes here
long long n;
std::cin >> n;
long long a[n];
for(long long i=0;i<n;i++)
{
    std::cin >> a[i];
}
sort(a,a+n);
long long max=LONG_MIN,count;
for(long long i=0;i<n;i++)
{
    if(a[i]*(n-i)>max)
    {
        max=a[i]*(n-i);
    }
}
std::cout << max << std::endl;
return 0;
}

答案 6 :(得分:-1)

我不知道我的答案是对还是错,如果有任何

,请指出错误
#include<stdio.h>
void main()
{
    register int i,j;
    long long int n,revenue;
    scanf("%Ld",&n);
    long long int a[n];
    for(i=0;i<n;i++)
        scanf("%Ld",&a[i]);
    for (i=0;i<n;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(a[i]>a[j])
            {
                a[i]=a[i]+a[j];
                a[j]=a[i]-a[j];
                a[i]=a[i]-a[j];
            }
        }
    }
    for(i=0;i<n;i++)
        a[i]=(n-i)*a[i];
    revenue=0;
    for(i=0;i<n;i++)
    {
        if(revenue<a[i])
            revenue=a[i];
    }
    printf("%Ld\n",revenue);
}