Pagini recente » Cod sursa (job #832216) | Cod sursa (job #1051759) | Cod sursa (job #425148) | Cod sursa (job #824251) | Cod sursa (job #1018601)
#include <cstdio>
using namespace std;
const int MAX_S = 10100;
const int MAX_N = 31;
const int MAX_K = 21;
const int MOD = 3210121;
int DP[MAX_N][MAX_S];
int C[MAX_N][MAX_N];
int k,s,n;
int arr[MAX_K][MAX_N];
int now[MAX_N];
long long sol;
void dynamic(){
for(int i = 0 ; i <= s ; ++ i)
DP[0][i] = 1;
for(int i = 1 ; i <= n ; ++ i)
for(int j = 0 ; j <= s ; ++ j){
DP[i][j] = DP[i-1][j];
if(j > 0)
DP[i][j] += DP[i][j-1];
if(DP[i][j] >= MOD)
DP[i][j] -= MOD;
}
C[0][0] = 1;
for(int i = 1 ; i <= n ; ++ i)
for(int j = 1 ; j <= n ; ++ j){
C[i][j] = C[i-1][j] + C[i-1][j-1];
if(C[i][j] >= MOD)
C[i][j] -= MOD;
}
}
inline void partial(const int taken, const int left){
if(taken < 1)
return;
const int sgn = -2 * (taken & 1) + 1;
sol += DP[n][left] * sgn;
}
void back(const int at, const int left, const int taken){
if(left < 0)
return;
if(at == k+1)
return partial(taken, left);
int old[MAX_N];
for(int i = 1 ; i <= n ; ++ i)
old[i] = now[i];
back(at + 1, left, taken);
int added = 0;
for(int i = 1 ; i <= n ; ++ i){
if(arr[at][i] > now[i]){
added += arr[at][i] - now[i];
now[i] = arr[at][i];
}
}
back(at + 1, left - added, taken + 1);
for(int i = 1 ; i <= n ; ++ i)
now[i] = old[i];
}
int main(){
freopen("cowfood.in", "r", stdin);
freopen("cowfood.out", "w", stdout);
scanf("%d%d%d", &n, &s, &k);
dynamic();
for(int i = 1 ; i <= k ; ++ i)
for(int j = 1 ; j <= n ; ++ j)
scanf("%d", &arr[i][j]);
back(1, s, 0);
sol += DP[n][s];
sol -= s * n + 1;
while(sol < 0)
sol += MOD;
while(sol >= MOD)
sol -= MOD;
printf("%lld\n", sol);
}