Cod sursa(job #321915)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 7 iunie 2009 19:14:45
Problema Cowfood Scor 18
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.57 kb
#include<stdio.h>
#include<string.h>
FILE*fin=fopen("cowfood.in","r");
FILE*fout=fopen("cowfood.out","w");

#define maxs 10005
#define maxk 35
#define mod 3210121
#define min(a,b)((a)<(b)?(a):(b))
#define max(a,b)((a)>(b)?(a):(b))

int a[maxk][maxk],comb[maxs+maxk][maxk],ac[maxk];
int n,k,s,ans;


int main()
{
  int i,j,c,nrl,sum;
    
  fscanf(fin,"%d%d%d",&k,&s,&n);
  
  for(i=1;i<=n;i++)
    for(j=1;j<=k;j++)
      fscanf(fin,"%d",&a[i][j]);
      
  //calcul combinari    
  //(numarul de modalitati de a distribui cel mult nrob obiecte identice in c cutii este comb[nrob+c][c])
  
  comb[0][0]=1;    
  
  for(i=1;i<=k+s;i++)
  {
    comb[i][0]=1;
    for(j=1;j<=min(k,i);j++)
    {
      comb[i][j]=comb[i-1][j-1]+comb[i-1][j];
      if(comb[i][j]>mod) comb[i][j]-=mod;
    }  
  }
  
  ans=0;
  for(i=k;i<=s;i++)  
  {
    ans+=comb[i-1][k-1];  
    if(ans>mod) ans-=mod;
  }  
  
  //fprintf(fout,"%d",ans);
  
  //solutie x puncte
  
  int ansr=0;
  for(c=1;c<(1<<n);c++)
  {
    nrl=0;    
    sum=0;               
    memset(ac,0,sizeof(ac));
    
    for(i=0;i<n;i++)
      if((1<<i)&c)
      {
        nrl++;
        for(j=1;j<=k;j++)
          ac[j]=max(ac[j],a[i+1][j]);
      }
    for(j=1;j<=k;j++)
      sum+=ac[j];
      
    if(sum>s) continue;
    
    if(nrl%2) ansr+=comb[k+s-sum][k];    
    else ansr-=comb[k+s-sum][k];    
    if(ansr<0) ansr+=mod;
    if(ansr>=mod) ansr-=mod;
  }
  ans=ans-ansr;
  if(ans<0) ans+=mod;
  fprintf(fout,"%d",ans);
  fclose(fin);
  fclose(fout);
  return 0;
}