Cod sursa(job #3293704)

Utilizator Allie28Radu Alesia Allie28 Data 12 aprilie 2025 13:07:17
Problema Cowfood Scor 16
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.95 kb
#include <bits/stdc++.h>

#define ll long long

using namespace std;

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

const int LMAX = 10;
const int LMAX2 = 10035;
const int INF = 0x3f3f3f3f;
const int MOD = 3210121;

int v[LMAX*2 + 5][LMAX*3 + 5], dp[10005], aux[LMAX*3 + 5], comb[LMAX2][LMAX2], s, k;

//|Ai| --> nr de submultimi care nu mai pot fi generate
//dp[i] --> nr de a face sume din k termeni, mai mici sau egale cu i

void precalc() {
    for (int i = 0; i <= s + k - 1; i++) {
        comb[i][0] = 1;
        for (int j = 1; j <= i; j++) {
            comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j])%MOD;
        }
        if (i > k - 1) {
//            fout<<i - k + 2<<" ";
            dp[i - k + 1] = (dp[i - k] + comb[i][k - 1])%MOD;
//            fout<<dp[i - k + 1]<<endl;
        }
    }
}

int main() {
    int n, i, j;
    fin>>k>>s>>n;
    for (i = 0; i < n; i++) {
        for (j = 0; j < k; j++) {
            fin>>v[i][j];
        }
    }
    if (k > s) {
        fout<<0;
        return 0;
    }
    //i stars, k - 1 bars
    //comb din i + k - 1 luate cate k - 1
    dp[0] = 1;
    precalc();
    ll ans = 0;
    int sign, sum;
    for (int mask = 1; mask < (1<<n); mask++) {
        sign = 0;
        for (i = 0; (1<<i) <= mask; i++) {
            if (mask&(1<<i)) {
                for (j = 0; j < k; j++) {
                    aux[j] = max(aux[j], v[i][j]);
                }
                sign = 1 - sign;
            }
        }
        sum = 0;
        for (j = 0; j < k; j++) {
            sum += aux[j];
            aux[j] = 0;
        }
        if (sum > s) continue;
        if (sign) {
            ans = (ans + dp[s - sum])%MOD;
        }
        else {
            ans = (ans - dp[s - sum])%MOD;
        }
        while (ans < 0) {
            ans += MOD;
        }
    }
    fout<<dp[s - k] - ans;


    fin.close();
    fout.close();
    return 0;
}