Pagini recente » Cod sursa (job #1250864) | Cod sursa (job #129636) | Cod sursa (job #529070) | Cod sursa (job #2130150) | Cod sursa (job #1700969)
/*
D[i][j] = in cate moduri pot pune exact j obiecte in i multimi
D[i][j] = D[i-1][0] + D[i-1][1] + ... + D[i-1][j]
generalizare:
D[i][j] = in cate moduri pot pune cel mult j obiecte in i multimi
D[i][j] = D[i-1][j] + D[i][j-1]
*/
#include <cstdio>
#include <algorithm>
#define DIM1 33
#define DIM2 10300
#define MOD 3210121
using namespace std;
int N, K, S, sol, sum, Current[DIM1];
int D[DIM2][DIM1], A[DIM1][DIM1], B[DIM1][DIM1];
void backTrack (int lev, int val) {
if (lev == N) { /* ok am atins o configuratie corecta, vad daca o scad/adun */
if (!val) return;
int sum = 0;
for (int i = 1; i <= K; i ++)
sum += Current[i];
if (sum > S) return;
if (val%2) sol = (sol + D[S-sum][K+1] + MOD) % MOD;
else sol = (sol - D[S-sum][K+1] + MOD) % MOD;
} else { /* configuratia nu este buna, incerc sa o imbunatatesc */
backTrack (lev + 1, val + 0); /* nu incerc sa adaug o reteta */
for (int i = 1; i <= K; i ++) {
B[lev][i] = Current[i];
Current[i] = max (Current[i], A[lev][i]);
}
backTrack (lev + 1, val + 1); /* incerc sa adaug o reteta */
for (int i = 1; i <= K; i ++)
Current[i] = B[lev][i];
}
return;
}
int main () {
freopen ("cowfood.in" ,"r", stdin );
freopen ("cowfood.out","w", stdout);
scanf ("%d %d %d", &K, &S, &N);
for (int i = 0; i < N; i ++)
for (int j = 1; j <= K; j ++)
scanf ("%d", &A[i][j]);
for (int j = 0; j <= K + 1; j ++)
D[0][j] = 1;
for (int i = 1; i <= S + 1; i ++) {
for (int j = 0; j <= K + 1; j ++) {
if (j == 0 || j == 1) D[i][j] = 1;
else D[i][j] = (D[i-1][j] + D[i][j-1]) % MOD;
}
}
backTrack (0, 0);
sol = (D[S][K+1] - sol + MOD) % MOD;
sol = (sol - S*K - 1 + MOD) % MOD;
printf ("%d\n", sol);
return 0;
}