Rezolvare completă PbInfo #1234 easydel

Victor are la dispoziție multe cuburi din lemn, toate de aceeași dimensiune, fiecare fiind colorat cu una din culorile 0, 1, 2, …, 9. El a inventat un joc sub forma unui algoritm:

  • Pasul 0 – Se inițializează variabila X cu zero.
  • Pasul 1 – Se aleg la întâmplare un număr de cuburi și se formează cu ele un șir. Cuburile din șir sunt lipite unul de altul.
  • Pasul 2 – Dacă toate cuburile din șir au aceeași culoare, atunci se afișează valoarea variabilei X și jocul se oprește. În caz contrar se trece la pasul 3.
  • Pasul 3 – Se alege o culoare C și apoi toate cuburile de culoarea C se elimină din șir. Locurile cuburilor eliminate rămân temporar libere.
  • Pasul 4 – Orice cub din șir va fi deplasat spre stânga lui, cât timp pozițiile vecine sunt libere. Se mărește X cu 1 la fiecare deplasare cu o poziție. Operațiile de deplasare se încheie când nu se mai pot efectua mutări spre stânga. Apoi se revine la pasul 2.

Cerința

Se consideră un șir cu cel puțin două elemente reprezentând culorile cuburilor din șir. Se cere să se calculeze valoarea maximă pe care o poate avea X.

Date de intrare

În fișierul easydel.in se află pe prima linie șirul dat. Cifrele din șir sunt scrise fără spații între ele.

Date de ieșire

În fișierul easydel.out se va scrie un singur număr reprezentând valoarea maximă pe care o poate avea X.

Restricții și precizări

  • Lungimea maximă a șirului de culori este 20000.

Exemplu

easydel.in

12132131123221

easydel.out

37

Explicație

Se elimină toate cuburile de culoare 1. Șirul rămas este _2_32_3__2322_. Numărul de mutări spre stânga va fi 1+2+2+3+5+5+5+5, deci X va crește cu 28. Șirul devine 23232322.

Dacă se vor elimina apoi cuburile de culoare 3, atunci șirul rămas va fi 2_2_2_22. Numărul de mutări spre stânga va fi 1+2+3+3, deci X va crește cu 9. Șirul va deveni 22222 și jocul se va opri. Valoarea lui X va fi 37.

Dacă la început se elimină cuburile de culoare 2, atunci se va obtine sirul 1_13_1311_3__1. X va crește cu 18. Șirul va deveni 113131131 și X va putea crește cu cel mult 10.

Dacă la început se elimină cuburile de culoare 3, atunci se va obține șirul 121_21_112_221, iar X va crește cu 17. Șirul va deveni 12121112221, iar X va putea crește cu cel mult 18.

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 easydel:

#include<fstream>
using namespace std;

ifstream  fin("easydel.in");
ofstream fout("easydel.out");
char s[20002];
int t[20002],nt;
int colour_number, best_effort[5000], sub[2][5000], nsub[2], q[21][21], qtr[21][21], nr[30], ap[30];

int effort(int subm, int colour){
    //efortul de a sterge culoarea colour dintre cele ramase in complementara lui subm
    int ef,i;
    ef=0;
    for(i=0;i<colour_number;i++){
        if((subm&(1<<i))==0){
            ef=ef+qtr[colour][i];
        }
    }
    return ef;
}

void calcul(){
    int i,j,k;
    //q[a][b] = cu cat se misca spre stanga cuburile de culoare a daca se sterg cuburile de culoare b
    for(i=0;i<nt;i++){
        k=t[i];
        nr[k]++;
        for(j=0;j<colour_number;j++){
            if(j!=k)
                q[k][j]+=nr[j];
        }
    }
    for(i=0;i<colour_number;i++){
        for(j=0;j<colour_number;j++){
            qtr[i][j] = q[j][i];
        }
    }
}

void solve(){
    int i,j,k,k1,k2,bj,bf,jl,l;
    for(i=0;i<(1<<colour_number);i++){
        best_effort[i]=0;
    }
    nsub[1]=1;
    sub[1][0]=0;
    for(k=0;k<colour_number;k++)
    {
        k2=k%2;
        k1=1-k2;
        nsub[k2]=0;
        for(i=0;i<nsub[k1];i++){
            j=sub[k1][i];//una din submultimile anterioare
            bj=best_effort[j];

            for(l=0;l<colour_number;l++){
                if((j&(1<<l))==0){
                    //l este o culoare ce inca nu a fost stearsa
                    jl=j|(1<<l);
                    bf=effort(jl,l);
                    if(best_effort[jl]==0){
                        sub[k2][nsub[k2]]=jl;
                        nsub[k2]++;
                    }
                    if(bj+bf>best_effort[jl]){
                        best_effort[jl]=bj+bf;
                    }
                }
            }
        }
    }
}


int main(){
    int i,j;
    fin>>s;
    for(i=0;i<=30;i++)ap[i]=-1;
    colour_number=0;
    for(i=0;s[i]!=0;i++){
        j=s[i]-48;
        if(ap[j]==-1){
            ap[j]=colour_number;
            t[i]=colour_number;
            colour_number++;
        }
        else{
            t[i]=ap[j];
        }
    }
    nt=i;
    //am redenumit culorile in ordinea in care se intalnesc , de la stanga spre dreapta
    //ca sa am spatiu compact de etichete de culori 1,2,...,colour_number
    calcul();
    solve();
    fout<<best_effort[(1<<colour_number)-1]<<"
";
    fout.close();
    fin.close();
    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 #1234 easydel

Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #1234 easydel 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!