Rezolvare completă PbInfo #2473 jbb

Ana şi Bogdan joacă un nou joc – JBB (Jocul „Borcane cu Bomboane”). Pe tabla de joc sunt plasate N borcane cu bomboane. Se ştie câte bomboane se află în fiecare borcan: în borcanul i sunt B i bomboane (1≤i≤N).

Ca de obicei, Ana începe jocul, iar apoi cei doi jucători mută alternativ. Fiind prima la mutare, Ana alege un borcan din care va lua toate bomboanele.

Pe tabla de joc sunt trasate săgeţi care unesc borcanele. Mai exact, de la fiecare borcan i pleacă o singură săgeată către un alt borcan j. Săgeţile indică modul în care jucătorii se deplasează pe tabla de joc. Dacă există săgeată de la borcanul i la borcanul j, iar un jucător a luat bomboanele din borcanul i, atunci adversarul său e obligat să se deplaseze la borcanul j. Dacă în borcanul j va găsi bomboane, este obligat să le ia pe toate. Dacă borcanul j este gol, atunci adversarul poate să aleagă un alt borcan care conţine bomboane şi continuă jocul.

Evident, scopul fiecărui jucător este să aibă, la finalul jocului (atunci când toate borcanele au fost golite) cât mai multe bomboane.

Cerința

Determinaţi numărul maxim de bomboane pe care Ana le-ar putea obţine respectând regulile jocului. Bineînţeles, atât Ana, cât şi Bogdan joacă optim (adică la orice pas, fiecare jucător va face cea mai bună mutare pe care poate să o facă).

Date de intrare

Fişierul de intrare jbb.in conţine pe prima linie numărul natural N, reprezentând numărul de borcane.
Pe cea de a doua linie sunt N numere naturale nenule separate prin câte un spaţiu B1 B2Bn reprezentând numărul de bomboane din fiecare borcan.
Pe cea de a treia linie se află N numere naturale separate prin spaţiu S1 S2Sn, unde Si reprezintă borcanul indicat de săgeata care plecă de la borcanul i (1≤i≤N).

Date de ieșire

Fişierul de ieşire jbb.out va conţine o singură linie pe care va fi scris un număr natural reprezentând numărul maxim de bomboane pe care Ana le poate obţine.

Restricții și precizări

  • 1 ≤ N ≤ 10000
  • 1 ≤ Bi ≤ 1000, pentru orice 1≤i≤N

Exemplu

jbb.in

8
3 1 8 20 7 5 6 10
6 5 7 4 3 8 2 1

jbb.out

36

Explicație

Ana mută prima şi alege borcanul 7 şi ia 6 bomboane.
Bogdan este obligat să meargă la borcanul 2 şi ia 1 bomboane.

Ana este obligată să meargă la borcanul 5 şi ia 7 bomboane.
Bogdan e obligat să meargă la borcanul 3 şi ia 8 bomboane. Ana e obligată să meargă la borcanul 7, dar acesta este gol, prin urmare poate alege un alt borcan plin.

Ana alege borcanul 4, de unde ia 20 de bomboane.
Bogdan e obligat să meargă tot la borcanul 4, dar acesta este deja gol, ca urmare poate alege un alt borcan plin. Bogdan alege borcanul 8 de unde ia 10 bomboane.

Ana este obligată să meargă la borcanul 1 de unde ia 3 bomboane.
Bogdan e obligat să meargă la borcanul 6 de unde ia 5 bomboane. Jocul s-a încheiat, fiindcă toate borcanele au fost golite. Ana a obţinut în total: 6+7+20+3=36 bomboane

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

//Emanuela Cerchez - 100 puncte
#include <cstdio>
#include <algorithm>
#define NMAX 10004
using namespace std;
FILE * fin=fopen("jbb.in","r");
FILE * fout=fopen("jbb.out","w");

struct ciclu {int lg, x, s1, s2;};

int p[NMAX];
int b[NMAX];
int v[2*NMAX];
int nrc;       //numarul de cicluri
ciclu c[NMAX];
bool uz[NMAX];
int n;
int rez;

void citire();
void cicluri();
void rezolvare_cicluri_impare();

int main()
{
 citire();
 cicluri();
 rezolvare_cicluri_impare();
 fprintf(fout,"%d\n",rez);
 fclose(fout);
 return 0;
}


void citire()
{int i;
fscanf(fin,"%d",&n);
for (i=1; i<=n; i++) fscanf(fin,"%d",&b[i]);
for (i=1; i<=n; i++) fscanf(fin,"%d",&p[i]);
}

void cicluri()
{
int i, j, lgc, suma1, suma2, s1, total, x, last;
for (i=1; i<=n; i++)
    if (!uz[i])
       {//incepe un ciclu
       //sa-l construim
       lgc=suma1=suma2=0;
       for (j=i; !uz[j]; j=p[j])
           {lgc++;
            v[lgc]=j;
            uz[j]=1;
            if (lgc%2) suma1+=b[j];
                else suma2+=b[j];
           }
        if (lgc%2==0) //ciclu de lungime para
            {if (suma1>=suma2) rez+=suma1;
               else rez+=suma2;}
            else
            {c[++nrc].lg=lgc;
             for (j=lgc+1; j<=2*lgc; j++) v[j]=v[j-lgc];
             total=suma1+suma2;
             s1=suma1; x=v[1];
             suma2=suma2+b[v[1]];
             if (suma2>s1) {s1=suma2; x=v[2];}
             for (j=3; j<=lgc; j++)
                 if (j%2==0)
                 {
                  suma2=suma2-b[v[j-2]]+b[v[j+lgc-1]];
                  if (suma2>s1) {s1=suma2; x=v[j];}
                 }
                 else
                 {
                   suma1=suma1-b[v[j-2]]+b[v[j+lgc-1]];
                   if (suma1>s1) {s1=suma1; x=v[j];}
                 }

             c[nrc].x=x; c[nrc].s1=s1; c[nrc].s2=total-s1;
            }
       }
}

bool compara(ciclu c1, ciclu c2)
{
  return c1.s1-c1.s2>c2.s1-c2.s2;
}

void rezolvare_cicluri_impare()
{int i;
 sort(c+1,c+nrc+1,compara);
 for (i=1; i<=nrc; i++)
     if (i%2) rez+=c[i].s1;
        else rez+=c[i].s2;
}

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 #2473 jbb

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