Cod sursa(job #2007853)

Utilizator Coroian_DavidCoroian David Coroian_David Data 4 august 2017 12:24:25
Problema Atac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 kb
/**
*   Rezolvarea : Dinamica + Greedy
*
*   Numarul de intrebari este < N.
*
*   Demonstratie:
*
*   Pentru 2 numere e evident gasim bitul diferit.
*   Pentru 3 numere la o intrebare daca nu sunt toti la fel raman 1 sau 2 cu acelasi.
*   Pentru 4 numere la o intrebare daca nu sunt toti la fel raman 1,2 sau 3 cu acelasi.
*   ...
*   Pentru N numere la o intrebare daca nu sunt toti la fel raman 1,2 ... sau N - 1 cu acelasi.
*
*   Cred ca asta ii ceva inductie.
*
*   Time Complexity : O(2^N*N*L*L + N*N*L) = O(2^N*N*N*N + N*N*L) = O(2^N*N^3 + N^2*L);
*
*   L.E:Metoda mai sus nu merge, sunt cateva cazuri in care ar trebui alesi poate altii decat cei initiali la intrebari
*
*   L.L.E:Am mai trimis deoarece credeam ca se poate ca bitul i sa se fi intrebat deja,
*   dar nu ar fi avut sens sa intrebi despre un bit cand toti intr-o grupa il au la fel.
*
*   L.L.L.E: Am bagat memoizare, dar nu e nevoie de lint, deoarece intra pe int, demonstratie de mai sus e corecta.
*
*   Una mai simpla :
*
*   Presupunem ca luam N, dar din N obtinem N + 1 numere, N + 1 > N, deci fals.
*
*   Pentru 5
*   01111
*   10111
*   11011
*   11101
*   11111
*
*   COROIAN DAVID, Satu Mare, ROMANIA
**/

#include <cstdio>

using namespace std;

FILE *f, *g;

const int sqrInf = 220000000;

int n, l;

int costBit[1009];

char s[1019];

int dp[33009];

int bit[1009];

void readFile()
{
    f = fopen("sobo.in", "r");

    fscanf(f, "%d%d\n", &n, &l);

    int i, j, p2 = 1;
    for(i = 1; i <= n; i ++)
    {
        fgets(s, 1009, f);

        for(j = 1; j <= l; j ++)
        {
            if(s[j - 1] == '1')
                bit[j] |= p2;
        }

        p2 *= 2;
    }

    for(i = 1; i <= l; i ++)
        fscanf(f, "%d", &costBit[i]);//, printf("%lld ", costBit[i]);
  //  printf("\n");

    fclose(f);
}

inline int mxa(int a, int b)
{
    return (a > b ? a : b);
}

inline int mna(int a, int b)
{
    return (a < b ? a : b);
}
void dynamics()
{
    int i;
    for(i = 0; i <= (1 << n) - 1; i ++)
        dp[i] = sqrInf;

    for(i = 0; i < n; i ++)
        dp[1 << i] = 0;

    dp[0] = 0;
}

int rez;

int getRez(int cod)
{
    if(dp[cod] != sqrInf)
        return dp[cod];

    int i, ones, zeros;
    for(i = 1;  i <= l; i ++)
    {
        ones = bit[i];
        zeros = ~ones;

        ones = ones & cod;
        zeros = zeros & cod;

        if(ones != 0 && zeros != 0)
            dp[cod] = mna(dp[cod], mxa(getRez(ones), getRez(zeros)) + costBit[i]);
    }

    return dp[cod];
}

void solve()
{
    dynamics();

    rez = getRez((1 << n) - 1);
}

void printFile()
{
    g = fopen("sobo.out", "w");

    fprintf(g, "%d\n", rez);

    fclose(g);
}

int main()
{
    readFile();

    solve();

    printFile();

    return 0;
}