Cod sursa(job #1303033)

Utilizator smaraldaSmaranda Dinu smaralda Data 27 decembrie 2014 15:59:18
Problema Cowfood Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.79 kb
#include<stdio.h>
#include<algorithm>
using namespace std;

const int MOD = 3210121, NMAX = 21, KMAX = 31, SMAX = 10005;
int a[NMAX][KMAX], comb[SMAX + KMAX][KMAX], esuat[KMAX], lim[KMAX];

inline bool testBit (int x, int bit) {
    return x & (1 << bit);
}

void genComb (int limi, int limj) {
    int i, j;

    for(i = 0; i <= limi; ++ i) {
        comb[i][0] = 1;
        for(j = 1; j <= i && j <= limj; ++ j)
            comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % MOD;
    }
}

int main() {
    freopen("cowfood.in", "r", stdin);
    freopen("cowfood.out", "w", stdout);
    int card, cnt, subset, newSum, total, naspa, i, j, n, k, s;

    scanf("%d%d%d", &k, &s, &n);
    for(i = 1; i <= n; ++ i)
        for(j = 1; j <= k; ++ j)
            scanf("%d", &a[i][j]);

    genComb(s + k - 1, k - 1);

    total = 0;
    for(i = 1; i <= s; ++ i)
        total = (total + comb[s + i - 1][i - 1]) % MOD;
    total -= k;
  //  fprintf(stderr, "%d\n", total);

    naspa = 0;
    for(subset = 1; subset <= (1 << n); ++ subset) {
        cnt = 0;
        for(i = 0; i < n; ++ i)
            if(testBit(subset, i)) {
                ++ cnt;

                for(j = 1; j <= k; ++ j)
                    lim[j] = max(lim[j], a[i + 1][j]);
            }

    /*    fprintf(stderr, "\n%d %d\n", subset, cnt);
        for(i = 1; i <= k; ++ i)
            fprintf(stderr, "%d ", lim[i]);
 */
        newSum = s;
        for(i = 1; i <= k; ++ i)
            newSum -= lim[i];
        
        card = 0;
        for(i = 1; i <= newSum; ++ i)
            card = (card + comb[newSum + i - 1][i - 1]) % MOD;

   //     fprintf(stderr, "%d\n", card);

        if(cnt % 2 == 1)
            naspa = (naspa + card) % MOD;
        else
            naspa = (naspa - card) % MOD;
    }

    printf("%d\n", (total - naspa) % MOD);
    return 0;
}