Pagini recente » Cod sursa (job #669631) | Cod sursa (job #1299421)
#include <fstream>
#include <cstring>
using namespace std;
const int kMaxN = 25, kMaxK = 35, kMaxS = 10105, kMod = 3210121;
ifstream fin("cowfood.in");
ofstream fout("cowfood.out");
int N, K, S, comb[kMaxS][kMaxK], test[kMaxN][kMaxK], lim[kMaxN][kMaxK], sign = 1, sol;
void Read() {
fin >> K >> S >> N;
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= K; ++j)
fin >> test[i][j];
}
void Comb() {
comb[0][0] = 1;
for (int i = 1; i < kMaxS; ++i) {
comb[i][0] = 1;
for (int j = 1; j < kMaxK; ++j)
comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % kMod;
}
for (int i = 1; i < kMaxS; ++i)
for (int j = 0; j < kMaxK; ++j)
comb[i][j] = (comb[i][j] + comb[i - 1][j]) % kMod;
}
inline int Sol(int sum, int cnt) {
if (sum < 0)
return 0;
return comb[sum + K - 1][K - 1];
}
void Back(int lv, int cnt) {
for (int crt = 0; crt < 2; ++crt) {
int nw_cnt = cnt + crt;
for (int i = 1; i <= K; ++i)
lim[lv][i] = max(lim[lv - 1][i], crt * test[lv][i]);
if (lv == N) {
int s = S;
for (int i = 1; i <= K; ++i)
s -= lim[N][i];
sol = (sol + kMod + Sol(s, nw_cnt) * sign) % kMod;
} else {
Back(lv + 1, nw_cnt);
}
sign *= -1;
}
}
int main() {
Read();
Comb();
if (!N)
sol = comb[S + K - 1][K - 1];
else
Back(1, 0);
sol = (sol + kMod - (K * S + 1) % kMod) % kMod;
fout << sol << "\n";
return 0;
}