Cod sursa(job #340144)

Utilizator misuvdPopovici Mihai misuvd Data 13 august 2009 12:54:22
Problema Cowfood Scor 58
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 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; 
  }  
  */   
  ans=(comb[k+s][k]-s*k-1+mod)%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;  
}