Cod sursa(job #881927)

Utilizator mlupseLupse-Turpan Mircea mlupse Data 18 februarie 2013 19:21:40
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <cstdio>
#include <algorithm>
#include <cassert>

using namespace std;

const int MaxN = 21;
const int MaxK = 31;
const int MaxS = 10005;
const int Mod = 3210121;

int N, K, S, Exp[MaxN][MaxK], DP[MaxK][MaxS], Sol;

void BuildDP() {
    for (int s = 0; s <= S; ++s)
        DP[0][s] = 1;
    for (int k = 1; k <= K; ++k) {
        for (int s = 0; s <= S; ++s) {
            DP[k][s] = DP[k-1][s];
            if (s > 0)
                DP[k][s] = (DP[k][s]+DP[k][s-1])%Mod;
        }
    }
}

void Back(int n, int Sign, int E[]) {
    if (n == N) {
        int Sum = S;
        for (int i = 0; i < K; ++i)
            Sum -= E[i];
        if (Sum >= 0)
            Sol = (Sol+Mod+Sign*DP[K][Sum])%Mod;
        return;
    }
    Back(n+1, Sign, E);
    int NewE[MaxK];
    for (int i = 0; i < K; ++i)
        NewE[i] = max(E[i], Exp[n][i]);
    Back(n+1, -Sign, NewE);
}

void Solve() {
    BuildDP();
    Sol = (Mod-S*K-1)%Mod;
    int E[MaxK];
    for (int i = 0; i < K; ++i)
        E[i] = 0;
    Back(0, 1, E);
}

void Read() {
    assert(freopen("cowfood.in", "r", stdin));
    assert(scanf("%d %d %d", &K, &S, &N) == 3);
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < K; ++j)
            assert(scanf("%d", &Exp[i][j]) == 1);
}

void Print() {
    assert(freopen("cowfood.out", "w", stdout));
    printf("%d\n", Sol);
}

int main() {
    Read();
    Solve();
    Print();
    return 0;
}