Cod sursa(job #2297526)

Utilizator flibiaVisanu Cristian flibia Data 5 decembrie 2018 22:52:08
Problema Cowfood Scor 24
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
#pragma GCC optimize("03")
#include <bits/stdc++.h>
#define MOD 3210121

using namespace std;

ifstream in("cowfood.in");
ofstream out("cowfood.out");

int k, s, n, ans, a[25][35], dp[35][10100], nr[35][10100], v[35];

void solve(int mask) {
	int cnt = __builtin_popcount(mask);
	memset(v, 0, sizeof v);	
	int f = 1;
	for (int bit = 0; bit < n; bit++)
		if (mask & (1 << bit))
			for (int i = 1; i <= k; i++)
				if (v[i] == 0)
					v[i] = a[bit][i];
				else if (v[i] != a[bit][i]) {
					f = 0;
					v[i] = max(v[i], a[bit][i]);
				}
	int cur = 0;	
	for (int i = 1; i <= k; i++)
		cur += v[i];
	cur = s - cur;
	if (cur < 0)
		return;
//	cout << cnt << ' ' << cur << ' ' << f << ' ' << nr[k][cur] << endl;
	if (cnt % 2 == 1)
		ans += nr[k][cur] - f;
	else ans -= nr[k][cur] - f;
	ans = (ans + MOD) % MOD;
}

int main() {
	in >> k >> s >> n;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
			in >> a[i][j];
//	for (int i = 1; i <= s; i++)
//		dp[1][i] = 1 + dp[1][i - 1];
//	for (int i = 2; i <= k; i++) {
//		for (int j = i; j <= s; j++)
//			dp[i][j] = dp[i - 1][j - 1];
//		for (int j = i; j <= s; j++)
//			dp[i][j] = (dp[i][j] + dp[i][j	 - 1]) % MOD; 
//	}
	for (int i = 1; i <= s; i++)
		dp[1][i] = 1;
	for (int i = 2; i <= s; i++)
		for (int j = 1; j < i; j++)
			dp[2][i] = (dp[2][i] + dp[1][j]) % MOD;
	for (int i = 3; i <= k; i++) {
		for (int j = 2; j <= s; j++) 
			for (int p = 0; p <= j; p++)
				if (p == 0)
					dp[i][j] = (dp[i][j] + dp[i - 1][j]) % MOD;
				else dp[i][j] = (dp[i][j] + dp[i - 1][j - p] + (i - 1) * (j > p));
	}
	for (int i = 1; i <= s; i++)
		dp[k][i] = (dp[k][i] + dp[k][i - 1]) % MOD;	
	for (int i = 0; i <= s; i++)
		nr[1][i] = 1;
	for (int i = 1; i <= s; i++)
		nr[1][i] += nr[1][i - 1];
	for (int i = 2; i <= k; i++) {
		for (int j = 0; j <= s; j++)
			nr[i][j] = nr[i - 1][j];
//		if (i < k)
			for (int j = 1; j <= s; j++)
				nr[i][j] = (nr[i][j] + nr[i][j - 1]) % MOD;
	}
//	for (int i = 0; i <= s; i++)
//		nr[1][i] = 1;
//	for (int i = 2; i <= k; i++)
//		for (int j = 0; j <= s; j++)
//			for (int p = 0; p <= j; p++)
//				nr[i][j] = (nr[i][j] + nr[i - 1][p]) % MOD;
//	for (int i = 1; i <= s; i++)
//		nr[k][i] = (nr[k][i] + nr[k][i - 1]) % MOD;
	for (int mask = 1; mask < (1 << n); mask++)
		solve(mask);
	out << (dp[k][s] - n - ans + MOD) % MOD;	
//	cout << dp[k][s] << endl; 
	return 0;
}