Pagini recente » Cod sursa (job #1265249) | Cod sursa (job #2393056) | Cod sursa (job #1578044) | Cod sursa (job #1273181) | Cod sursa (job #3030720)
/*
1 ≤ N, M ≤ 16 => O(2^n * n * m) => Backtracking
Backtracking = algoritm care genereaza toate variantele posibile
Exemple: Generare de permutari, Submultimi, ...
Flip: Care ar fi toate variantele posibile? => Toate posibilitatile de a flipui
linii si coloane.
L1L3L5L8C2C4C6 <=> L1C2L3L5C4L8C6
Fiecare linie / coloana are 2 posibilitati: flip sau no flip
Toate posibilitatile = Orice submultime de linii si coloane
{L1, L2, L3, L4, C1, C2, C3}:
1) {L1, L4, C2} => suma1
2) {L2, L3, C1} => suma2
3) {C1, C2} => suma3
...
O multime cu n elemente are exact 2^n submultimi distincte.
{1, 2, 3}
000 => {}
001 => {3}
010 => {2}
011 => {2, 3}
100 => {1}
101 => {1, 3}
110 => {1, 2}
111 => {1, 2, 3}
{1, 2, 3, ..., n} => 2 * 2 * ... * 2 => 2^n
Nu intra O(2^(n + m)) dar intra O(2^n * n * m) => Intra in timp sa generez
toate submultimile posibilie de linii / sau coloane (DOAR UNA)
Pt fiecare submultime de linii => flip liniile alea => flip coloanele negative
*/
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
// Backtracking e despre decizii. Deciziile sunt ca pentru fiecare linie de la 1 la n
// sa decidem daca o adaugam in submultime sau nu
vector<int> submultime;
int n, m, a[20][20], sol = -INT_MAX;
void flip_line(int line) {
for(int col = 1; col <= m; col++) {
a[line][col] *= -1;
}
}
void backtracking(int lin) {
// Punct de oprire:
if (lin == n + 1) {
// Submultimea e generata. Hai sa aflam solutia pt aceasta submultime
for(int linie : submultime) {
flip_line(linie);
}
int total = 0;
for(int col = 1; col <= m; col++) {
int sum_col = 0;
for(int lin = 1; lin <= n; lin++) {
sum_col += a[lin][col];
}
total += abs(sum_col);
}
sol = max(sol, total);
for(int linie : submultime) {
flip_line(linie);
}
return;
}
// Decizii:
// Caz 1: adaug linia lin in submultime:
submultime.push_back(lin);
backtracking(lin + 1); // imi genereaza toate submultimile care contin linia 1
// Caz 2: nu adaug linia lin:
submultime.pop_back();
backtracking(lin + 1); // imi genereaza toate submultimile care nu contin linia 1
}
int main() {
ifstream fin("flip.in");
ofstream fout("flip.out");
fin >> n >> m;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
fin >> a[i][j];
}
}
backtracking(1);
fout << sol << "\n";
return 0;
}