Cod sursa(job #1018507)

Utilizator ericptsStavarache Petru Eric ericpts Data 29 octombrie 2013 18:11:22
Problema Cowfood Scor 4
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.64 kb
#include <cstdio>

using namespace std;

const int MAX_S = 10100;
const int MAX_N = 31;
const int MAX_K = 21;
const int MOD = 3210121;

int DP[MAX_N][MAX_S];

int k,s,n;

int arr[MAX_K][MAX_N];
int now[MAX_N];

long long sol;

void dynamic(){
    DP[0][0] = 1;
    for(int i = 1 ; i <= n ; ++ i)
        for(int j = 1 ; j <= s ; ++ j){
            DP[i][j] = DP[i][j-1] + DP[i-1][j-1];
            if(DP[i][j] >= MOD)
                DP[i][j] -= MOD;
        }
}

inline void partial(const int taken, const int left){
    if(taken < 1)
        return;
    const int sgn = -2 * (taken & 1) + 1;

    sol += DP[n][left + n] * sgn;
    if(sol >= MOD)
        sol -= MOD;
    else if(sol < 0)
        sol += MOD;
}

void back(const int at, const int left, const int taken){
    if(left < 0)
        return;

    if(at == k+1)
        return partial(taken, left);

    int old[MAX_N];
    for(int i = 1 ; i <= n ; ++ i)
        old[i] = now[i];

    back(at + 1, left, taken);

    int added = 0;
    for(int i = 1 ; i <= n ; ++ i){
        if(arr[at][i] > now[i]){
            added += arr[at][i] - now[i];
            now[i] = arr[at][i];
        }
    }

    back(at + 1, left - added, taken + 1);
    for(int i = 1 ; i <= n ; ++ i)
        now[i] = old[i];

}

int main(){
    freopen("cowfood.in", "r", stdin);
    freopen("cowfood.out", "w", stdout);
    scanf("%d%d%d", &n, &s, &k);
    dynamic();
    for(int i = 1 ; i <= k ; ++ i)
        for(int j = 1 ; j <= n ; ++ j)
            scanf("%d", &arr[i][j]);
    sol = DP[n][s];
    back(1, s, 0);
    sol %= MOD;
    printf("%lld\n", sol);
}