Cod sursa(job #132446)

Utilizator mgntMarius B mgnt Data 5 februarie 2008 20:47:28
Problema Zebughil Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

typedef long long int bigint;

ifstream sin  ( "zebughil.in" );
ofstream sout ( "zebughil.out" );

class Test {
public:
  int rezultat();
private:
  enum { MAXN = 17 };
  int n, g, z[MAXN];

  void dfs (int r);
  int ramas[MAXN];
  bigint risipaPosibila;
  bigint risipa;

  int k;
  
};

int Test::rezultat() {
  int i, num;
  sin >> n >> g; for(i=0;i<n;i++) sin >> z[i];
  make_heap(&z[0], &z[n]); sort_heap(&z[0], &z[n]);
  bigint sumaZ = 0; for(i=0;i<n;i++) sumaZ += z[i];
  if(0 == sumaZ) { sout << 0 << endl; return 0; }
  bigint sumaG = 0; for(k=0;sumaZ>sumaG;k++) sumaG += g;
  bigint gPe2 = g/2; num = 0; for(i=0;i<n;i++) if(gPe2<z[i]) ++ num;
  if (num>k) k=num;
  risipa = 0;
  try {
    while (true) {
      for(i=0;i<k;i++) ramas[i]=g;
      risipaPosibila = sumaG - sumaZ;
      dfs(n-1);
      ++ k;
      sumaG += g;
    }
  } catch (int rezultat) {
    k = rezultat;
  }
  return k;
}

void Test::dfs(int r) {
  int i;
  if(0 == r) {
    for(i=0;i<k;i++) if (ramas[i] >= z[0]) throw k;
    return;
  }
  for(i=0;i<k;i++) {
    if(ramas[i] >= z[r]) {
      bigint tmpRisipa = risipa;
      ramas[i] -= z[r];
      if(z[0] > ramas[i]) {
        if (risipa + ramas[i] > risipaPosibila) {
          ramas[i] += z[r];
          continue;
        }
        risipa += ramas[i];
      }
      dfs(-1+r);
      ramas[i] += z[r];
      risipa = tmpRisipa;
    }
  }
}

void test () {
  Test t;
  sout << t.rezultat() << endl;
}

int main () {
  test(); test(); test();
  return 0;
}