Pagini recente » Cod sursa (job #15049) | Istoria paginii runda/oji_2005_10/clasament | Cod sursa (job #166426) | Cod sursa (job #17258) | Cod sursa (job #1493956)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxN 22
#define maxS 1002
#define maxK 32
#define mod 3210121
using namespace std;
int n, s, k, i, j, dp[maxS][maxN], sp[maxS][maxN], S[maxS][maxN];
int a[maxN][maxK], b[maxK], sol, lpow2[maxN];
void read()
{
freopen("cowfood.in", "r", stdin);
scanf("%d %d %d", &n, &s, &k);
for (i = 0; i < n; ++ i)
for (j = 1; j <= k; ++ j)
scanf("%d", &a[i][j]);
}
void DP()
{
int p2 = 1;
lpow2[p2] = 0;
dp[0][0] = 1;
for (i = 0; i <= s; ++ i)
sp[i][0] = 1;
for (i = 1; i <= k; ++ i)
{
S[0][i] = 1;
p2 *= 2;
lpow2[p2] = i;
for (j = 1; j <= s; ++ j)
{
S[j][0] = 1;
dp[j][i] = sp[j - 1][i - 1];
sp[j][i] = (sp[j - 1][i] + dp[j][i]) % mod;
S[j][i] = S[j][i - 1] + S[j - 1][i];
}
}
sol = sp[s][k];
}
void solve()
{
int p2 = 1 << n, m, p, sum, nb1;
bool ok;
DP();
for (i = 1; i < p2; ++ i)
{
m = i;
sum = 0;
ok = 1;
nb1 = 0;
memset(b, 0, sizeof(b));
do
{
p = lpow2[m ^ (m & (m - 1))];;
++ nb1;
for (j = 1; j <= k; ++ j)
{
if (b[j] < a[p][j])
{
sum -= b[j];
b[j] = a[p][j];
sum += b[j];
}
if (sum > s)
{
ok = 0;
break;
}
}
}while (m &= m - 1);
if (!ok)
break;
if (nb1 % 2)
sol -= S[s - sum][k];
else
sol += S[s - sum][k];
if (sol > mod)
sol -= mod;
if (sol < 0)
sol += mod;
}
}
void write()
{
freopen("cowfood.out", "w", stdout);
printf("%d", sol);
}
int main()
{
read();
solve();
write();
return 0;
}