Cod sursa(job #1580714)

Utilizator lflorin29Florin Laiu lflorin29 Data 26 ianuarie 2016 01:35:16
Problema Cowfood Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <bits/stdc++.h>

using namespace std;

const int md = 3210121, SMAX = 1 << 14, KMAX = 32;

int c[SMAX][KMAX], a[KMAX][KMAX];
int part[SMAX][KMAX];
int k, s, n;
int act[1 << 20][KMAX];

void citire() {
    ifstream fin("cowfood.in");
    fin >> k >> s >> n;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < k; ++j)
           fin >> a[i][j];
}

void add(int &a, int b) {
    a += b;
    if(a >= md)
        a %= md;
    else if(a < 0)
    for(; a < 0; a += md);
}

int ways(int suma, int cate) {
    return c[suma + cate - 1][cate - 1];
}

void precalc() {
    for(int i = 0; i < SMAX; ++i)
        c[i][0] = 1;
    for(int i = 1; i < SMAX; ++i)
        for(int j = 1; j < KMAX; ++j)
             add(c[i][j], c[i - 1][j] + c[i - 1][j - 1]);
    for(int i = 0; i < SMAX; ++i)
        for(int j = 1; j < KMAX; ++j)
           part[i][j] = ways(i, j);
    for(int i = 1; i < SMAX; ++i)
        for(int j = 0; j < KMAX; ++j)
            add(part[i][j], part[i - 1][j]);
}

int rasp(int snow) {
    if(snow < 0) return 0;
    int Ret = part[snow][k];
    return Ret;
}


void solve() {
    int Ret = 0;
    for(int i = 2; i <= s; ++i)
        add(Ret, ways(i, k) - k);
    for(int i = 0; i < n; ++i)
       memcpy(act[1 << i], a[i], sizeof(act[1 << i]));
    for(int i = 1; i < 1 << n; ++i)
        for(int j=0;j<n;++j)
           if(i&(1<<j))
             for(int ult = 0; ult < k; ++ult)
           act[i][ult] = max(act[i][ult], act[i ^ (1 << j)][ult]);
    for(int i=1;i<1<<n;++i){
        int sum=0;
        for(int j=0;j<k;++j)
           add(sum,act[i][j]);
        int crt=__builtin_popcount(i);
        sum=rasp(s-sum);
        if(crt & 1)
            add(Ret,-sum);
        else add(Ret,sum);
    }
    ofstream("cowfood.out") << Ret;
}

int main() {
    citire();
    precalc();
    solve();
}