[Grundkurs zum Acwing-Algorithmus] Kapitel 6 Greedy-Sorting-Ungleichung-913. Anstehen, um Wasser zu holen

Die am Greedy-Problem beteiligten Modelle wurden alle in der Mathematik untersucht, und die Beweislogik muss streng sein.

Die schriftlichen Testfragen erfordern einen relativ hohen Zeitaufwand und Sie müssen rechnen können. Die Interviewfragen erfordern sowohl einen zeitlichen als auch einen räumlichen Aufwand.

Thema:

Es stehen n Personen Schlange, um Wasser aus einem Wasserhahn zu holen. Die Zeit, die die i-te Person benötigt, um das Wasser aufzufüllen, beträgt ti. Wie kann die Reihenfolge beim Wasserholen festgelegt werden, um die Summe der Wartezeiten aller zu minimieren?

Eingabeformat

Die erste Zeile enthält die ganze Zahl n.

Die zweite Zeile enthält n Ganzzahlen, wobei die i-te Ganzzahl die Zeit ti darstellt, die die i-te Person benötigt, um den Eimer zu füllen.  

Ausgabeformat

Geben Sie eine Ganzzahl aus, die die Mindestsumme der Wartezeiten darstellt

Datenreichweite

1 <= n <= 105

1 <= ti <= 104

Eingabebeispiel

7 //7 Leute holen Wasser
3 6 1 4 2 5 7 //Jeder hat Zeit, Wasser zu holen

Ausgabebeispiel

56

Idee:

  1. Auf den ersten warten alle, auf den zweiten warten n-1 Personen. Je weiter hinten, desto weniger Personen warten

    Gesamtzeit = t1 (n-1) + t2 (n-2) + ... + tn-1 * 1

  1. Platzieren Sie also diejenigen, die eine kurze Zeit verwenden, vorne und diejenigen, die eine lange Zeit verwenden, hinten.

  2. Stellen Sie sich in der Reihenfolge vom kleinsten zum größten mit der kürzesten Gesamtzeit in die Warteschlange

beweisen:

Beweis durch Widerspruch: Wenn es sich nicht um ein Inkrement handelt, führt der Austausch bestimmter zwei zu besseren Ergebnissen. Daher muss es ein Inkrement sein, um den Mindestwert zu erhalten

Code

von acwing Ich habe den Kommentar hinzugefügt

#include <iostream>
#include <algorithm>
//贪心 排序不等式 913.排队打水
using namespace std;

const int N = 100010;

typedef long long LL;
int n;
int t[N];

int main(){
    scanf("%d",&n);//读取人数
    for(int i = 0;i < n;i++) scanf("%d",&t[i]);//读取每个人的打水时间
    sort(t,t + n);//每个人的时间排序
    //结果可能爆int 改成LL
    LL res = 0;
    for(int i = 0;i < n;i++){
        res += t[i] * (n - i - 1);//打水时间*等待的人数
    }
    printf("%lld\n",res);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_65293439/article/details/128462640