Pagini recente » Cod sursa (job #3216993) | Cod sursa (job #2290211) | Cod sursa (job #2679052) | Cod sursa (job #2530482) | Cod sursa (job #3293704)
#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;
}