Cod sursa(job #376728)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 22 decembrie 2009 13:25:58
Problema Cowfood Scor 2
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.42 kb
#include <cstdio>
#include <cstring>

#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define max(a,b) (a > b ? a : b)

#define IN  "cowfood.in"
#define OUT "cowfood.out"
#define mod 3210121

int P[32][1<<14],A[32][1<<14],V[32][32],K,S,N;
int stv[32];

void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d%d",&K,&S,&N);
	
	FOR(i,1,N)
	FOR(j,1,K)
		scanf("%d",&V[i][j]);
}

int back1(int poz,int cfg)
{
	if(poz == K+1)
	{
		int nr(0);
		FOR(i,1,K)
			if(cfg & (1<<i) )
				++nr;
		return nr < 2 ? 0 : A[nr][S - nr] + 1;
	}
	
	return (back1(poz+1,cfg) + back1(poz+1,cfg | (1<<poz))) % mod;
}

int back2(int poz,int cfg)
{
	if(poz == K+1)
	{
		if(!cfg)
			return 0;
		
		int nr(0),total = S;
		FOR(i,1,K)
			total -= stv[i],nr += cfg & (1<<i);
		return total < 0 ? 0 : (A[K][total] + 1) * (nr & 1 ? -1 : 1);
	}
	
	int rez = back2(poz+1,cfg);
	
	int aux[32]={0};
	CP(aux,stv);
	FOR(i,1,K) stv[i] = max(stv[i],V[poz][i]);
	
	rez += back2(poz+1,cfg | (1<<poz));
	
	CP(stv,aux);
	return rez % mod;
}

void solve()
{
	FOR(i,1,K)
		P[i][1] = i;
	FOR(i,1,K)
	FOR(j,2,S)
		P[i][j] = (P[i-1][j] + P[i][j-1]) % mod;
	
	FOR(i,1,K)
	FOR(j,1,S)
		A[i][j] = (A[i][j-1] + P[i][j]) % mod;
	
	int rez = back1(1,0) - back2(1,0);
	if(rez < 0) rez += mod;
	printf("%d\n",rez);
}

int main()
{
	scan();
	solve();
	return 0;
}