Cod sursa(job #2247213)

Utilizator gabib97Gabriel Boroghina gabib97 Data 27 septembrie 2018 23:40:21
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <bits/stdc++.h>

#define N 31
#define S 10001
#define W 3210121

using namespace std;

int k, n, s, T[N][N], total[S][N], all, min_qty[N][N], subset[N], sum[S], part_sum[S];

void back(int ik) {
    int min_sum, nr, nr_not_null;
    for (int i = subset[ik - 1] + 1; i <= n; i++) {
        subset[ik] = i;

        min_sum = nr_not_null = 0;
        for (int j = 1; j <= k; j++) {
            min_qty[ik][j] = max(T[i][j], min_qty[ik - 1][j]);
            if (min_qty[ik][j] > 0)
                nr_not_null++;
            min_sum += min_qty[ik][j];
        }

        nr = 0;
        if (s >= min_sum) {
            nr = part_sum[s - min_sum];

            // don't count invalid mixtures
            if (nr_not_null == 0)
                nr -= 1 + k * s;
            else if (nr_not_null == 1)
                nr -= s - min_sum;
        }

        if (ik % 2) all = (all - nr) % W;
        else all = (all + nr) % W;

        if (ik < n) back(ik + 1);
    }
}

int main() {
    ifstream fin("cowfood.in");
    ofstream fout("cowfood.out");

    fin >> k >> s >> n;

    int i, j;
    for (i = 1; i <= n; i++)
        for (j = 1; j <= k; j++)
            fin >> T[i][j];

    // compute total number of experiments
    // total[s][nr_types] = nr of experiments with nr_types food types and the sum = s
    for (i = 0; i <= s; i++) total[i][1] = 1;
    for (i = 0; i <= k; i++) total[0][i] = sum[i] = 1;

    for (i = 1; i <= s; i++) {
        sum[1]++;
        for (j = 2; j <= k; j++) {
            total[i][j] = (total[i][j] + sum[j - 1]) % W;
            sum[j] = (sum[j] + total[i][j]) % W;
        }
    }

    part_sum[0] = 1;
    for (i = 1; i <= s; i++) {
        all = (all + total[i][k]) % W;
        part_sum[i] = (part_sum[i - 1] + total[i][k]) % W;
    }
    all -= k * s; // don't count experiments with less than two >0 types.

    back(1);
    if (all < 0) all = W + all % W;
    fout << all;

    return 0;
}