Rezolvare completă PbInfo #2500 parcare1

Într-o țară în curs de dezvoltare, într-un oraș oarecare, parcarea pe care primăria dorește să o construiască are formă dreptunghiulară și o putem codifica folosind o matrice cu L linii (numerotate de la 1 la L) și C coloane (numerotate de la 1 la C). Practic, pentru a o pava pe toată ar fi necesari L x C metri pătrați de dale. Firma care produce dalele și care este agreată de primar construiește dale cu lățimea de un metru și lungime care poate fi mai mare de un metru (dar o valoare întreagă). Firma asamblează dalele în pachete și toate pachetele au exact același conținut (dalele unui pachet pot avea lungimi diferite). Pentru că risipa banului public este în perioada sa de apogeu, primarul hotărăște să cumpere pentru fiecare coloană a parcării câte un pachet de dale și nu va putea folosi la pavarea acelei coloane decât dale din acel pachet. Se mai cunoaște și că în fiecare coloană este plantat exact un copac iar acesta nu va putea fi tăiat. Considerăm că un copac ocupă exact zona corespunzătoare unei dale 1 x 1.

Cerința

După ce un consilier atrage atenția că e posibil ca structura pachetului achiziționat să nu permită pavarea oricărei coloane, primarul nefiind de acord cu această ipoteză hotărăște să te angajeze ca programator și să îi spui care este numărul de variante distincte de pavare a parcării. La numărarea variantelor trebuie ținut cont că toate dalele dintr-un pachet sunt de culori diferite. Considerăm distincte două modalități de pavare dacă există cel puțin o coloană unde același loc este acoperit de dale de culori diferite.

Date de intrare

Fișierul de intrare parcare1.in conține pe prima linie numerele: N (numărul de dale dintr-un pachet), L (numărul de linii ale parcării), C (numărul de coloane ale parcării). Linia a doua conține N valori naturale nenule reprezentând lungimile dalelor (ele au lățimea 1). Pot fi dale de aceeași dimensiune, ele diferă însă prin culoare. Linia a treia conține C numere, al i-lea reprezentând linia pe care se află copacul de pe coloana i. Numerele de pe fiecare linie sunt separate prin câte un spațiu.

Date de ieșire

Fișierul de ieșire parcare1.out conține numărul de modalități de pavare, modulo 666013.

Restricții și precizări

  • 1 ≤ N ≤ 20
  • 2 ≤ L ≤ 20
  • 1 ≤ C ≤ 100 000
  • Lungimile dalelor sunt numere naturale nenule mai mici decât L
  • Valorile de pe ultima linie a fișierului de intrare sunt cuprinse între 1 și L, inclusiv

Exemplu

parcare1.in

5 7 2
1 2 3 4 5
4 2

parcare1.out

12

Cum e corect?

cout < "As la info"; cout << "As la info"; cout >> "As la info";

Felicitări! Poți mai mult?

Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.

Greșit, dar nu-i bai!

Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.

Rezolvare

Iată rezolvarea de 100 de puncte pentru problema parcare1:

#include <fstream>
#include <cstring>
#define DIM 22
#define MOD 666013
using namespace std;
int n, m, h, L[DIM], v[100010];
int D[DIM][DIM][DIM][DIM], E[DIM][DIM][DIM][DIM];
int suma, sol, i, j, si, sj, imaxim, jmaxim, simaxim, sjmaxim, x;
int I, J, SI, SJ, s, k, F[DIM], S[DIM], A[DIM];

int main () {
    ifstream fin ("parcare1.in");
    ofstream fout("parcare1.out");
    fin>>n>>h>>m;
    F[0] = 1;
    for (i=1;i<=h;i++)
        F[i] = F[i-1] * 1LL * i % MOD;

    for (i=1;i<=n;i++)
        fin>>L[i];
    for (i=1;i<=m;i++) {
        fin>>v[i];
    }

    D[0][0][0][0] = E[0][0][0][0] = 1;
    imaxim = 0;
    jmaxim = 0;
    simaxim = 0;
    sjmaxim = 0;
    for (s = 1; s<=n; s++) {
        I = imaxim;
        J = jmaxim;
        SI = simaxim;
        SJ = sjmaxim;
        for (i=0;i<=imaxim;i++)
            for (j=0;j<=jmaxim;j++)
                for (si = 0; si <= simaxim; si++)
                    for (sj = 0; sj <= sjmaxim && si + sj < h; sj++)
                        if (D[sj][si][j][i] != 0) {
                            if (si + L[s] <= h) {
                                E[sj][si + L[s]][j][i+1] += D[sj][si][j][i];
                                if (E[sj][si + L[s]][j][i+1] >= MOD)
                                    E[sj][si + L[s]][j][i+1] -= MOD;
                                if (i+1 > I)
                                    I = i+1;
                                if (si + L[s] > SI)
                                    SI = si + L[s];
                            }
                            if (sj + L[s] <= h) {
                                E[sj + L[s]][si][j+1][i] += D[sj][si][j][i];
                                if (E[sj + L[s]][si][j+1][i] >= MOD)
                                    E[sj + L[s]][si][j+1][i] -= MOD;
                                if (J < j+1)
                                    J = j+1;
                                if (sj + L[s] > SJ)
                                    SJ = sj + L[s];
                            }
                        }

        imaxim = I;
        jmaxim = J;
        simaxim = SI;
        sjmaxim = SJ;
        ///memcpy(D, E, sizeof(D));

        for (i=0;i<=imaxim;i++)
            for (j=0;j<=jmaxim;j++)
                for (si = 0; si <= simaxim; si++)
                    for (sj = 0; sj <= sjmaxim; sj++)
                        D[sj][si][j][i] = E[sj][si][j][i];

    }

    sol = 1;
    for (k=1;k<=m;k++) {
        if (A[v[k]]) {
            sol = sol * 1LL * A[ v[k] ] % MOD;
            continue;
        }
        suma = 0;
        if (v[k] == 1 || v[k] == h) {
            for (i=1;i<=n;i++) {
                suma += D[0][h-1][0][i] * 1LL * F[i] % MOD;
                suma %= MOD;
            }
            A[ v[k] ] = suma;
            sol = sol * 1LL * suma % MOD;
            continue;
        }
        for (i=1;i<=n;i++)
            for (j=1;j<=n;j++) {
                suma += (D[h-v[k]][v[k]-1][j][i] * 1LL * F[i] % MOD * 1LL * F[j] % MOD);
            }
        A[v[k]] = suma;
        suma %= MOD;
        sol = sol * 1LL * suma % MOD;
    }

    fout<<sol;
    return 0;
}

Atenție

Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa Adresa de email.

Rezolvarea problemei #2500 parcare1

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2500 parcare1 de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.

Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!