Pagini recente » Cod sursa (job #700932) | Cod sursa (job #2494816) | Cod sursa (job #2750701) | Cod sursa (job #2694432) | Cod sursa (job #3331019)
// /*
// enunt:
// ai N camere in linie: 0, 1, .., N-1, fiecare are un bec (0 - stins, 1 - aprins)
// exista M intrerupatoare (cel putin 1 in fiecare camera). un intrerupator aflat in camera C:
// - intotdeauna schimba starea becului din camera C;
// - poate schimba si becuri din camere cu index mai mare decat C;
// - actionarea lui costa T timp;
// schimbarea starii: toggle intre 0 si 1
// scop: sa ajungi ca in toate camerele sa fie becul aprins (1) cu timp total minim
// solutie:
// de ce nu merge un algoritm de la stanga-dreapta
// pentru o camera i:
// - intrerupatoarele din camere mai mari (> i) NU au voie sa ii modifice becul (un intrerupator
// modifica becul din camera sa si eventual dupa ea)
// - deci dupa ce ai trecut de i, nu mai poti modifica becul din i
// asta face decizia ca la camera i sa fie fortata:
// - daca atunci cand ajungi la i, becul este 0, trebuie doar sa apesi intrerupatorul din i ca sa l aprinzi
// - daca e 1, nu l apesi (altfel l ai stinge si nu mai ai cum sa l reaprinzi mai tarziu)
// prin urmare, solutia minima este practic deterministica: parcurgi camerele in ordine si apesi exact unde este nevoie
// (Alg de tip Greedy)
// algoritm:
// citesti n si m
// citesc starea initiala a becurilor in a[0..n-1]
// citesti toate intrerupatoarele in vectorul v[], avand:
// - poz = camera unde este intrerupatorul
// - t = timpul de apasare
// - nr = camera modificata
// - c[] = lista camerelor modificate (include mereu poz)
// parcurgerea intrerupatoarelor si pentru fiecare:
// - daca in camera lui (a[poz]) becul este stins, apasa
// - daca face toggle pentru toate camerele din lista c[]
// - adauga timpul t in sum
// scrie sum
// */
// #include <bits/stdc++.h>
// using namespace std;
// // Pentru fiecare cameră putem avea cel mult un întrerupător.
// struct SwitchInfo {
// bool exists = false; // există întrerupător în camera asta?
// int t = 0; // timpul de apăsare
// int nr = 0; // câte camere modifică
// int c[105]; // lista camerelor modificate (nr <= 100)
// };
// int main() {
// ifstream fin("aprindere.in");
// ofstream fout("aprindere.out");
// int n, m;
// fin >> n >> m;
// // a[i] = starea becului din camera i (0/1)
// int a[1001];
// for (int i = 0; i < n; i++) fin >> a[i];
// // sw[C] = întrerupătorul din camera C (dacă există)
// SwitchInfo sw[1001];
// for (int k = 0; k < m; k++) {
// int C, T, NRC;
// fin >> C >> T >> NRC;
// sw[C].exists = true;
// sw[C].t = T;
// sw[C].nr = NRC;
// for (int j = 0; j < NRC; j++) {
// fin >> sw[C].c[j];
// }
// }
// long long sum = 0;
// // Parcurgem camerele în ordine (0..N-1).
// // IMPORTANT: după ce trecem de i, nimic din dreapta nu mai poate modifica camera i.
// for (int i = 0; i < n; i++) {
// if (!sw[i].exists) {
// // În teste există mereu soluție, deci dacă i e 0 acum, înseamnă că a fost
// // aprinsă din întrerupătoare anterioare. (Sau era deja 1.)
// continue;
// }
// // Dacă becul din camera i este stins când ajungem aici, trebuie apăsat.
// if (a[i] == 0) {
// // Apăsăm întrerupătorul: toggle pe toate camerele din lista lui.
// for (int j = 0; j < sw[i].nr; j++) {
// int room = sw[i].c[j];
// a[room] ^= 1; // toggle: 0->1, 1->0
// }
// sum += sw[i].t;
// }
// // Dacă a[i] e deja 1, nu apăsăm (altfel l-am stinge și nu îl mai putem repara).
// }
// fout << sum;
// return 0;
// }
#include <bits/stdc++.h>
using namespace std;
ifstream fin("aprindere.in");
ofstream fout("aprindere.out");
int n, m;
int bec[1005];
struct Intrerupator {
int poz;
int timp;
int nr;
int c[105];
};
Intrerupator v[1005];
bool exista[1005];
int ind[105];
void citire() {
fin >> n >> m;
for (int i = 0; i < n; i++)
fin >> bec[i];
for (int i = 0; i < m; i++) {
fin >> v[i].poz >> v[i].timp >> v[i].nr;
for (int j = 0; j < v[i].nr; j++)
fin >> v[i].c[j];
exista[v[i].poz] = true;
ind[v[i].poz] = i;
}
}
void apasare(int k) {
for (int i = 0; i < v[k].nr; i++) {
int camera = v[k].c[i];
bec[camera] = 1 - bec[camera];
}
}
int rez() {
int timptot = 0;
for (int i = 0; i < n; i++) {
if (exista[i]) {
if (bec[i] == 0) {
int k = ind[i];
timptot += v[k].timp;
apasare(k);
}
}
}
return timptot;
}
int main() {
citire();
fout << rez();
return 0;
}