简体   繁体   English

将 O(n^2) 的复杂度降低到至少 O(n log n)

[英]Reducing complexity of O(n^2) to at least O(n log n)

I want to reduce complexity of this program but I don't know how.我想降低这个程序的复杂性,但我不知道如何。

Program:程序:
You are holding an event and you need money.你正在举办一个活动,你需要钱。 Every person that participates will give percentage of their salary to the event, but every person must give the same percentage.每个参与的人都会将其工资的百分比用于活动,但每个人都必须提供相同的百分比。 If the percentage you chose is for example 30% and person P is only willing to give 20%, then person P wont give anything.例如,如果您选择的百分比是 30%,而 P 只愿意付出 20%,那么 P 不会给予任何东西。 If you chose 30% and person P is willing to give 80%, then person P will only give 30%.如果你选择了 30%,而 P 愿意付出 80%,那么 P 只会付出 30%。

You want to figure out what is the percentage that will get you the most money.你想弄清楚能让你赚到最多钱的百分比是多少。

Inputs are:输入是:

First line: Number of people that participate (n)第一行:参与人数(n)
Next n lines: Salary of i-th person, Max percentage of salary that i-th person is willing to give away下 n 行:第 i 人的薪水,第 i 人愿意放弃的薪水的最大百分比

Output: Output:
First line: Largest amount of money that you can get for the event.第一行:您可以为该活动获得的最大金额。

Example:例子:

Input:输入:

 4 100001 83.2 40001 20 90001 77.32 300001 1.88

Output: Output:

 146909.5464

Program chose that the percentage that will bring the most money is 77.32 and wrote that the money you can get from that percentage is (100001+90001)*77.32程序选择了能带来最多钱的百分比是 77.32,并写道你可以从这个百分比中得到的钱是 (100001+90001)*77.32

#include <iostream>
#include <iomanip>

using namespace std;

int N,A[200000];
double P[200000],suma,maxsuma;

int main(){

ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

cin>>N;
for(int i=0;i<N;i++){
    cin>>A[i]>>P[i];
}
for(int i=0;i<N;i++){
    suma=0;
    for(int j=0;j<N;j++){
        if(P[j]>=P[i]){
            suma+=P[i]*A[j]/100.0;
        }
    }
    maxsuma=max(suma,maxsuma);
}

cout<<fixed<<setprecision(20)<<maxsuma;

}

First, sort all your people by the percentage they are willing to give descending.首先,按照他们愿意给出的百分比降序排列所有员工。 Now whatever percentage you pick, only some first people on the list would actually pay.现在,无论您选择什么百分比,只有名单上的第一批人会真正付钱。 Therefore, you would make the most profit-making it the last person percentage.因此,您将获得最大的利润,使其成为最后一个人的百分比。 Now also notice, that from this prefix everyone gives salary * percentage , so the total payment would be total salary * percentage .现在还要注意,从这个前缀每个人都给出salary * percentage ,所以总支付将是total salary * percentage If s[i] is the total salary from all people up to i-th index, than s[i] = s[i - 1] + a[i] where a[i] is i-th person salary.如果s[i]是直到第 i 个索引的所有人的总工资,则s[i] = s[i - 1] + a[i]其中 a[i] 是第 i 个人的工资。 Therefore you just write a loop that would first count s[i] using known s[i - 1] from the previous iteration, and then multiply it by the percentage of i-th person;因此,您只需编写一个循环,首先使用上一次迭代中已知s[i - 1]计算s[i] ,然后将其乘以第 i 个人的百分比; across all such values pick the highest one.在所有这些值中选择最高的值。

I modified your code to use this idea.我修改了你的代码来使用这个想法。

#include <iostream>
#include <iomanip>
#include <algorithm>

using namespace std;

int N;
std::pair<int, int> A[200000]
double maxsuma;

int main(){

ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);

cin>>N;
for(int i=0;i<N;i++){
    cin>>A[i].second>>A[i].first;
}
std::sort(A, A + N, std::greater<std::pair<int, int>>());
int suma = 0;
for(int i=0;i<N;i++){
    suma += A[i].second;
    maxsuma=max(suma * A[i].first / 100.0, maxsuma);
}

cout<<fixed<<setprecision(20)<<maxsuma;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM