Tree DP (Memorized Search) PAT Klasse A 1079 1090 1106

Baum-DP: Wird verwendet, um den Abstand von jedem Knoten im Baum zum Wurzelknoten zu ermitteln

Vorlage:

int dfs(int i){
    if(f[i] != -1) return f[i];
    if(p[i] == -1) return f[i] = 0;
    return f[i] = dfs(p[i]) + 1;
}

Original-Titellink:

1079 Gesamtumsatz der Lieferkette

1090 Höchstpreis der Lieferkette

1106 Der niedrigste Preis in der Lieferkette

Thema:

Gesamter Supply-Chain-Umsatz

Eine Lieferkette ist ein Vertriebsnetzwerk aus Einzelhändlern, Distributoren und Lieferanten, von denen jeder am Prozess des Produkttransports vom Lieferanten zum Kunden beteiligt ist.

Das gesamte Vertriebsnetz kann als Baumstruktur betrachtet werden. Vom Stammlieferanten abwärts kaufen alle, nachdem sie Waren vom Lieferanten der oberen Ebene gekauft haben, unter der Annahme, dass der Kaufpreis P ist, zu einem Preis, der r% über dem Kaufpreis liegt . Der Preis wird nach unten verkauft.

Nur Einzelhändler (d. h. Blattknoten) können Produkte direkt an Kunden verkaufen.

Berechnen Sie nun bitte für das gesamte Vertriebsnetz den Gesamtumsatz aller Einzelhändler.

Die erste Zeile des Eingabeformats
enthält drei Zahlen: N stellt die Gesamtzahl der Mitglieder in der Lieferkette dar (alle Mitglieder sind von 0 bis N−1 nummeriert und die Stammlieferantennummer ist 0), P stellt den jeweiligen Verkaufspreis dar Produkt des Stammlieferanten, r, der Prämienprozentsatz.

In den nächsten N Zeilen enthält jede Zeile die Informationen eines Mitglieds. Das Format ist wie folgt:

Ki ID[1] ID[2] … ID[Ki]
In der i-ten Zeile stellt Ki die Anzahl der Mitglieder dar, die Waren direkt vom Lieferanten i kaufen, und die nächsten Ki-Ganzzahlen sind die Anzahl jedes Kaufmitglieds.

Wenn der Kj einer bestimmten Zeile 0 ist, bedeutet dies, dass es sich um einen Einzelhändler handelt. Anschließend folgt nur eine Zahl, die die Gesamtzahl der an Kunden verkauften Produkte angibt.

Ausgabeformat
Geben Sie den Gesamtumsatz aus, behalten Sie eine Dezimalstelle bei.

Datenbereich
1≤N≤105,
0<P≤1000,
0<r≤50
Jeder Einzelhändler hat nicht mehr als 100 Produkte.
Die endgültige Antwort wird 1010 garantiert nicht überschreiten.

Eingabebeispiel:
10 1,80 1,00
3 2 3 5 1
9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3
Ausgabebeispiel:
42,4

Meine Lösung:

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

const int N = 100010;
double R, P;
int p[N], f[N], cnt[N];

int dfs(int i){
    if(f[i] != -1) return f[i];
    if(p[i] == -1) return f[i] = 0;
    return f[i] = dfs(p[i]) + 1;
}
int main(){
    int n;
    cin >> n >> P >> R;
    memset(f, -1, sizeof f);
    memset(p, -1, sizeof p);
    for(int i = 0; i < n; i ++ ){
        int k;
        cin >> k;
        for(int j = 0; j < k; j ++ ){
            int son;
            cin >> son;
            p[son] = i;
        }
        
        if(k == 0) cin >> cnt[i];
    }
    
    double res = 0;
    for(int i = 0; i < n; i ++ ){
        if(cnt[i]){
            res += cnt[i] * P * pow(1 + R/100, dfs(i));
        }
    }
    
    printf("%.1lf", res);
    return 0;
}

Der höchste Preis in der Lieferkette

Eine Lieferkette ist ein Vertriebsnetzwerk aus Einzelhändlern, Distributoren und Lieferanten, von denen jeder am Prozess des Produkttransports vom Lieferanten zum Kunden beteiligt ist.

Das gesamte Vertriebsnetz kann als Baumstruktur betrachtet werden. Vom Stammlieferanten abwärts kaufen alle, nachdem sie Waren vom Lieferanten der oberen Ebene gekauft haben, unter der Annahme, dass der Kaufpreis P ist, zu einem Preis, der r% über dem Kaufpreis liegt . Der Preis wird nach unten verkauft.

Nur Einzelhändler (d. h. Blattknoten) können Produkte direkt an Kunden verkaufen.

Berechnen Sie nun bitte anhand des gesamten Vertriebsnetzes den höchsten Verkaufspreis, den der Händler erzielen kann.

Eingabeformat
Die erste Zeile enthält drei Zahlen: N steht für die Gesamtzahl der Mitglieder in der Lieferkette (alle Mitglieder sind von 0 bis N−1 nummeriert); P steht für den Produktverkaufspreis des Stammlieferanten; r steht für den Prämienprozentsatz.

Die zweite Zeile enthält N Zahlen, und die i-te Zahl Si ist die Nummer des übergeordneten Lieferanten der Mitgliedsnummer i. Der Root-Anbieter hat einen Sroot von -1.

Ausgabeformat
Gibt den höchsten Verkaufspreis aus, den ein Einzelhändler erzielen kann, gerundet auf zwei Dezimalstellen, sowie die Anzahl der Einzelhändler, die den höchsten Verkaufspreis erzielen können.

Der Datenbereich ist
1 ≤ N ≤ 105,
0 < P ≤ 1000,
0 < r ≤ 50 und
die endgültige Antwort wird 1010 garantiert nicht überschreiten.

Eingabebeispiel:
9 1,80 1,00
1 5 4 4 -1 4 5 3 6
Ausgabebeispiel:
1,85 2

Meine Lösung:

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

const int N = 100010;
int n;
double P, R;
int p[N], f[N];

int dfs(int i){
    if(f[i] != -1) return f[i];
    if(p[i] == -1) return f[i] = 0;
    return f[i] = dfs(p[i]) + 1;
}

int main(){
    cin >> n >> P >> R;
    
    memset(p, -1, sizeof p);
    for(int i = 0; i < n; i ++ ){
        int father;
        cin >> father;
        p[i] = father;
    }
    
    memset(f, -1, sizeof f);
    
    int cnt = 0, res = 0;
    for(int i = 0; i < n; i ++ ){
        if(dfs(i) > res){
            res = dfs(i);
            cnt = 1;
        }
        else if(dfs(i) == res) cnt ++;
    }
    
    printf("%.2lf %d", P * pow(1 + R / 100, res), cnt);
    return 0;
}

Der niedrigste Preis in der Lieferkette

Eine Lieferkette ist ein Vertriebsnetzwerk aus Einzelhändlern, Distributoren und Lieferanten, von denen jeder am Prozess des Produkttransports vom Lieferanten zum Kunden beteiligt ist.

Das gesamte Vertriebsnetz kann als Baumstruktur betrachtet werden. Vom Stammlieferanten abwärts kaufen alle, nachdem sie Waren vom Lieferanten der oberen Ebene gekauft haben, unter der Annahme, dass der Kaufpreis P ist, zu einem Preis, der r% über dem Kaufpreis liegt . Der Preis wird nach unten verkauft.

Nur Einzelhändler (d. h. Blattknoten) können Produkte direkt an Kunden verkaufen.

Berechnen Sie nun bitte anhand des gesamten Vertriebsnetzes, welchen Mindestverkaufspreis der Händler erzielen kann.

Die erste Zeile des Eingabeformats
enthält drei Zahlen: N stellt die Gesamtzahl der Mitglieder in der Lieferkette dar (alle Mitglieder sind von 0 bis N−1 nummeriert, und die Stammlieferantennummer ist 0), P stellt den Produktverkaufspreis dar der Stammlieferant, r, der Prämienprozentsatz.

In den nächsten N Zeilen enthält jede Zeile die Informationen eines Mitglieds. Das Format ist wie folgt:

Ki ID[1] ID[2] … ID[Ki]
In der i-ten Zeile stellt Ki die Anzahl der Mitglieder dar, die Waren direkt vom Lieferanten i kaufen, und die nächsten Ki-Ganzzahlen sind die Anzahl jedes Kaufmitglieds.

Wenn Kj 0 ist, bedeutet dies, dass das j-te Mitglied ein Einzelhändler ist.

Ausgabeformat
Gibt den niedrigsten Verkaufspreis aus, den ein Einzelhändler erzielen kann, gerundet auf vier Dezimalstellen, sowie die Anzahl der Einzelhändler, die den niedrigsten Verkaufspreis erzielen können.

Datenbereich
1≤N≤105,
0<P≤1000,
0<r≤50,
die endgültige Antwort wird garantiert 1010 nicht überschreiten.
Eingabebeispiele:
10 1,80 1,00
3 2 3 5
1 9
1 4 1
7
0
2 6 1
1 8
0
0
0
Ausgabebeispiel:
1,8362 2

Meine Lösung:

#include <bits/stdc++.h>
using namespace std;
const int N = 100010, INF = 1e9;
int n;
double P, R;
int p[N], f[N];
bool is_leaf[N];

int dfs(int i){
    if(f[i] != -1) return f[i];
    if(p[i] == -1) return f[i] = 0;
    return f[i] = dfs(p[i]) + 1;
}

int main(){
    cin.tie();
    cin >> n >> P >> R;
    memset(p, -1, sizeof p);

    for(int i = 0; i < n; i ++ ){
        int k;
        cin >> k;
        for(int j = 0; j < k; j ++ ){
            int son;
            cin >> son;
            p[son] = i;
        }
        if(k == 0) is_leaf[i] = true;
    }
    

    memset(f, -1, sizeof f);
    int res = INF, cnt = 0;
    for(int i = 0; i < n; i ++ ){
        if(is_leaf[i]){
            if(dfs(i) < res){
                res = dfs(i);
                cnt = 1;
            }
            else if(dfs(i) == res) cnt ++ ;
        }
    }
    
    printf("%.4lf %d", P * pow(1 + R / 100, res), cnt);
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45660485/article/details/126082343