Cod sursa(job #1867402)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 4 februarie 2017 01:38:43
Problema Cowfood Scor 38
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.29 kb
#include <bits/stdc++.h>

using namespace std;

const int KMAX = 31, SMAX = 10010, NMAX = 21;
const int MOD = 3210121;

int K, S, N;
int E[NMAX][KMAX];
int DP[KMAX][SMAX];
int DP2[1 << NMAX][KMAX], where[1 << NMAX];

int main() {
	assert(freopen("cowfood.in", "r", stdin));
	assert(freopen("cowfood.out", "w", stdout));

	int i, j;

	cin >> K >> S >> N;
	for (i = 0; i < N; ++i)
		for (j = 0; j < K; ++j)
			cin >> E[i][j];

	DP[0][0] = 1;
	for (i = 1; i <= K + 1; ++i) {
		DP[i][0] = 1;
		for (j = 1; j <= S; ++j) {
			DP[i][j] = DP[i - 1][j] + DP[i][j - 1];
			if (DP[i][j] >= MOD)
				DP[i][j] -= MOD;
		}
	}

	for (i = 0; i < N; ++i)
		where[1 << i] = i;

	int answer = 0;
	for (i = 1; i < (1 << N); ++i) {
		int prev_state = i & (i - 1);
		int diff = where[i ^ prev_state];
		int sum = 0;
		for (j = 0; j < K; ++j) {
			DP2[i][j] = max(DP2[prev_state][j], E[diff][j]);
			sum += DP2[i][j];
		}
		int cnt = 0;
		for (j = 0; j < N; ++j)
			if (i & (1 << j))
				++cnt;
		if (cnt & 1) {
			answer -= DP[K + 1][S - sum];
			if (answer < 0)
				answer += MOD;
		} else {
			answer += DP[K + 1][S - sum];
			if (answer >= MOD)
				answer -= MOD;
		}
	}

	answer = ((answer + DP[K + 1][S] - 1 - K * S) % MOD + MOD) % MOD;
	cout << answer << '\n';

	return 0;
}