Cod sursa(job #1491886)

Utilizator livliviLivia Magureanu livlivi Data 26 septembrie 2015 12:47:10
Problema Cowfood Scor 18
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.4 kb
#include<cstdio>
#define S 10000
#define K 30
#define N 20
#define M 3210121
using namespace std;

int C[S+K][K];
int a[N][K+1];
int v[K+1];

int s,n,k;


int max(int a,int b){
    return (a<b) ? b : a;
}

int min(int a,int b){
    return (a<b) ? a : b;
}


void precC(){
    int i,j,x;

    for(i=0;i<s+k;i++){
        C[i][0]=1;

        x=min(i+1,k);
        for(j=1;j<x;j++){
            C[i][j]=C[i-1][j]+C[i-1][j-1]-M;
            if (C[i][j]<0) C[i][j]+=M;
        }
    }

    for(i=k;i<s+k;i++){
        C[i][k-1]=C[i][k-1]+C[i-1][k-1]-M;
        if (C[i][k-1]<0) C[i][k-1]+=M;
    }
}


long long solve(){
    long long R=C[s+k-3][k-1];
    int i,j,l;
    int cnt,nr;

    for(i=1;i<(1<<n);i++){
        cnt=0;
        nr=s;
        for(l=1;l<=k;l++)
            v[l]=0;

        for(j=0;j<n;j++)
            if (((1<<j)&i)!=0){
                cnt++;
                for(l=1;l<=k;l++)
                    v[l]=max(v[l],a[j][l]);
            }

        for(l=1;l<=k;l++)
            nr-=v[l];

        if (nr>=0) nr+=(k-1);
        if ((cnt&1)==0) R=R+C[nr][k-1]-M;
        else R=R-C[nr][k-1];
        if (R<0) R+=M;
    }

    return R;
}


int main(){
    freopen ("cowfood.in","r",stdin);
    freopen ("cowfood.out","w",stdout);
    int i,j;

    scanf ("%d%d%d",&k,&s,&n);

    for(i=0;i<n;i++)
        for(j=1;j<=k;j++)
            scanf ("%d",&a[i][j]);

    precC();

    printf ("%lld",solve());
    return 0;
}