Cod sursa(job #2386935)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 23 martie 2019 22:32:18
Problema Cowfood Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.56 kb
#include <bits/stdc++.h>

using namespace std;

FILE *fin = fopen ("cowfood.in", "r"), *fout = fopen ("cowfood.out", "w");

const int MAXK = 30, MAXS = 10000, MOD = 3210121;

int dp[MAXK + 1][MAXS + 1], a[MAXK + 1], v[MAXK + 1][MAXK + 1];

int n, k, s, sol;

void back (int poz, int pm, int sum) {
  if (poz > n) {
    if (sum <= s && sum > 0) {
      if (pm % 2) {
        sol = (sol + dp[k][s - sum]) % MOD; // s - s1 se pot alege liber
      }
      else
        sol = (sol - dp[k][s - sum] + MOD) % MOD;
    }
  }
  else {
    int aux[40];
    int i;
    for (i = 1; i <= k; i++)
      aux[i] = a[i];
    back (poz + 1, pm, sum);
    sum = 0;
    for (i = 1; i <= k; i++) {
      a[i] = max (a[i], v[poz][i]);
      sum = sum + a[i];
    }
    back (poz + 1, pm + 1, sum);
    for (i = 1; i <= k; i++)
      a[i] = aux[i];
  }
}

int main() {
  int i, j;
  fscanf (fin, "%d%d%d", &k, &s, &n);
  // calculam numarul de moduri de submultimi care au suma elementelor mai mica ca s
  // dp[i][j] = numarul de submultimi cu i elemente care au suma mai mica ca j
  for (j = 0; j <= s; j++)
    dp[1][j] = j + 1;
  for (i = 2; i <= k; i++) {
    dp[i][0] = 1; // k elemente de 0
    for (j = 1; j <= s; j++)
      dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % MOD;
  }
  sol = (dp[k][s] - s * k + MOD) % MOD;
  for (i = 1; i <= n; i++)
    for (j = 1; j <= k; j++)
      fscanf (fin, "%d", &v[i][j]);
  back (1, 1, 0);
  sol--;
  if (sol < 0)
    sol = sol + MOD;
  fprintf (fout, "%d\n", sol);
  fclose (fin);
  fclose (fout);
  return 0;
}