Pagini recente » Cod sursa (job #835673) | Cod sursa (job #509597) | Cod sursa (job #211975) | Cod sursa (job #2760088) | Cod sursa (job #2611806)
#include <fstream>
using namespace std;
ifstream fin("cowfood.in");
ofstream fout("cowfood.out");
const int MOD = 3210121, NMax = 20, KMax = 30, SMax = 10000;
int V[NMax + 5], N, K, S, A[NMax + 5][KMax + 5], C[SMax + KMax + 5][KMax + 5], Maxi[NMax + 5][KMax + 5], W[NMax], Sol;
bool Use[NMax + 5];
///Hint: PINEX, Stars and Bars, Hockey stick theorem
int Shrink(int x)
{
if(x >= MOD)
x -= MOD;
return x;
}
void Process(int len, int Sum)
{
if(S - Sum + K < 0)
return;
if(len & 1)
Sol = Shrink(Sol + C[S - Sum + K][K]);
else
Sol = Shrink(Sol + MOD - C[S - Sum + K][K]);
}
void BKT(int pos)
{
for(int i = V[pos - 1] + 1; i <= N; i++)
{
if(Use[i]) continue;
V[pos] = i;
Use[i] = true;
for(int k = 1; k <= K; k++)
{
Maxi[pos][k] = max(Maxi[pos - 1][k], A[i][k]);
W[pos] += Maxi[pos][k];
}
Process(pos, W[pos]);
if(pos < N)
BKT(pos + 1);
Use[i] = false;
W[pos] = 0;
}
}
void Precalc()
{
for(int i = 0; i <= S + K; i++)
C[i][0] = 1;
for(int i = 1; i <= S + K; i++)
for(int j = 1; j <= K; j++)
C[i][j] = Shrink(C[i - 1][j] + C[i - 1][j - 1]);
}
int main()
{
fin >> K >> S >> N;
for(int i = 1; i <= N; i++)
for(int j = 1; j <= K; j++)
fin >> A[i][j];
Precalc();
BKT(1);
int Total = Shrink(C[S + K][K] + MOD - (K * S + 1) % MOD);
fout << Shrink(Total + MOD - Sol) << '\n';
fin.close();
fout.close();
return 0;
}