Cod sursa(job #2239401)

Utilizator LucaSeriSeritan Luca LucaSeri Data 10 septembrie 2018 18:02:46
Problema Cowfood Scor 48
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <fstream>
using namespace std;

typedef pair< int, int > pii;
typedef pair< long long, long long > pll;
typedef long long ll;
typedef vector< int > vi;
typedef vector< ll > vll;
typedef vector< pii > vpii;
typedef long double ld;

ll lgput(ll a, ll b, ll mod) {
    ll ret = 1;
    while( b ){
        if(b & 1) ret = (ret * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }

    return ret;
}

int binarySearch(vector< int > &v, int value) {
    int best = 0;
    for(int step = 29; step >= 0; --step) {
        if(best + (1<<step) < v.size() && v[best + (1<<step)] <= value) best += (1<<step);
    }

    return best;
}

const int MOD = 3210121;

const int MAXS = 1e4 + 50;
const int MAXN = 25;
const int MAXK = 35;

int comb[MAXS];
int k, s, n;
int recipes[MAXK][MAXN];
int ans = 0;
int currentMax[MAXK];

void backt(int niv, int cnt) {
    if(niv == n) {
        int sum = 0;

        for(int i = 0; i < k; ++i) {
            sum += currentMax[i];
        }

        if(sum > s) return;

        if(cnt & 1) {
            ans -= comb[s - sum];
        } else {
            ans += comb[s - sum];
        }

        while(ans >= MOD) ans -= MOD;
        while(ans < 0) ans += MOD;
        return;
    }

    backt(niv + 1, cnt);

    int nivMax[MAXK];
    for(int i = 0; i < k; ++i) {
        nivMax[i] = currentMax[i];
        currentMax[i] = max(currentMax[i], recipes[niv][i]);
    }

    backt(niv + 1, cnt + 1);

    for(int i = 0; i < k; ++i) {
        currentMax[i] = nivMax[i];
    }
}
int main() {
    ios::sync_with_stdio(false);

    FILE *f = fopen("cowfood.in", "r");
    FILE *g = fopen("cowfood.out", "w");

    fscanf(f, "%d%d%d", &k, &s, &n);

    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < k; ++j) {
            fscanf(f, "%d", &recipes[i][j]);
        }
    }

    for(int i = 0; i < MAXS; ++i) comb[i] = 1;
    for(int i = 0; i < k; ++i) {
        for(int j = 1; j < MAXS; ++j) {
            comb[j] = (comb[j] + comb[j-1]);
            if(comb[j] >= MOD) comb[j] -= MOD;
        }
    }

    backt(0, 0);
    ///Scadem pe cele care nu au macar 2 nenule
    fprintf(g, "%d\n", ((ans + (MOD - s*k - 1))%MOD + MOD) % MOD);
    fclose(f);
    fclose(g);
    return 0;
}