Cod sursa(job #341315)

Utilizator misofMiso Forisek misof Data 18 august 2009 04:37:38
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.48 kb
#include <numeric>
#include <fstream>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

int MOD = 3210121;
int C[10044][32];

int K, S, N;
int V[32];
int F[32][32];

int lo[1024][32], hi[1024][32];

int main() {
  ifstream fin("cowfood.in"); ofstream fout("cowfood.out");
  fin >> K >> S >> N;
  for (int n=0; n<N; ++n) for (int k=0; k<K; ++k) fin >> F[n][k];

  for (int s=0; s<=S+K; ++s) for (int k=0; k<=K; ++k) {
    if (k>s) C[s][k]=0;
    else if (k==s || k==0) C[s][k]=1;
    else C[s][k]=(C[s-1][k-1]+C[s-1][k]) % MOD;
  }

  int total = (C[S+K][K] - K*S - 1) % MOD;

  for (int k=0; k<K; ++k) lo[0][k] = hi[0][k] = -1;
  for (int ber=1; ber<(1<<10); ++ber) if (ber < (1<<N)) {
    int i=0; while (!(ber & 1<<i)) ++i;
    for (int k=0; k<K; ++k) lo[ber][k] = max( lo[ber ^ 1<<i][k], F[i][k] );
  }
  for (int ber=1; ber<(1<<10); ++ber) if ((ber<<10) < (1<<N)) {
    int i=0; while (!(ber & 1<<i)) ++i;
    for (int k=0; k<K; ++k) hi[ber][k] = max( hi[ber ^ 1<<i][k], F[i+10][k] );
  }

  for (int ber=1; ber<(1<<N); ++ber) {
    int sgn = 1;
    for (int i=0; i<N; ++i) if (ber & 1<<i) sgn *= -1;
    for (int k=0; k<K; ++k) V[k] = max( lo[ber & 1023][k], hi[ber >> 10][k] );
    // for (int i=0; i<N; ++i) if (ber & 1<<i) for (int k=0; k<K; ++k) V[k] = max( V[k], F[i][k] );
    int sum = 0;
    for (int k=0; k<K; ++k) sum += V[k];
    int cnt = (sum > S) ? 0 : C[S-sum+K][K];
    total = (total + sgn * cnt ) % MOD;
  } 
  total += MOD; total %= MOD;
  fout << total << endl;
}