Pagini recente » Cod sursa (job #1145755) | Cod sursa (job #321878) | Cod sursa (job #890403) | Cod sursa (job #1281948) | Cod sursa (job #1745238)
/**
* Worg
*/
#include <cstdio>
#include <algorithm>
using namespace std;
FILE *fin = freopen("cowfood.in", "r", stdin);
FILE *fout = freopen("cowfood.out", "w", stdout);
const int MAX_K = 1 + 30;
const int MAX_S = 1 + 10000;
const int MAX_N = 1 + 20;
const int MOD = 3210121;
/*---------------------*/ /** General */
int K, S, N;
int a[MAX_N][MAX_K];
/*---------------------*/ /** DP & Pinex */
int dp[MAX_K][MAX_S], dp_2[MAX_K][MAX_S];
int maxA[MAX_K];
/*---------------------*/
void readData() {
scanf("%d%d%d", &K, &S, &N);
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= K; j++) {
scanf("%d", &a[i][j]);
}
}
}
void generateDP() {
for(int i = 0; i <= S; i++) {
dp[0][i] = dp_2[0][i] = 1;
}
for(int i = 0; i <= K; i++) {
dp_2[i][0] = 1;
}
for(int i = 1; i <= K; i++) {
for(int j = 1; j <= S; j++) {
dp[i][j] = (dp[i][j - 1] + dp[i - 1][j - 1]);
dp[i][j] %= MOD;
dp_2[i][j] = (dp_2[i][j - 1] + dp_2[i - 1][j]);
dp_2[i][j] %= MOD;
}
}
}
int Pinex(int mask) {
int countExp = 0;
int sign;
for(int i = 1; i <= N; i++) {
if(mask & (1 << (i - 1))) {
countExp++;
for(int j = 1; j <= K; j++) {
maxA[j] = max(maxA[j], a[i][j]);
}
}
}
if(countExp % 2 == 1) {
sign = -1;
} else {
sign = 1;
}
int unUsed = S;
for(int i = 1; i <= K; i++) {
unUsed -= maxA[i];
maxA[i] = 0; /* we reset the values afterwards */
}
if(unUsed >= 0) {
return dp_2[K][unUsed] * sign;
} else {
return 0;
}
}
int countValidExperiments() {
int answer = dp[K][S];
const int maxMask = 1 << K;
for(int i = 1; i < maxMask; i++) {
answer = (answer + Pinex(i));
while(answer < 0) {
answer += MOD;
}
answer %= MOD;
}
return answer;
}
int main() {
readData();
generateDP();
printf("%d", countValidExperiments());
return 0;
}