Cod sursa(job #1990147)

Utilizator GoogalAbabei Daniel Googal Data 10 iunie 2017 17:09:49
Problema Bibel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
#include <iostream>
#include <fstream>
#include <cassert>

using namespace std;

ifstream in("morcovi.in");
ofstream out("morcovi.out");

const int PMAX = 1 << 15;
const int NMAX = 1000;
const int DIM = 100000;

int poz, n, p, dp[1 + PMAX][1 + NMAX], cost[1 + NMAX], v[1 + 12], sol;
char buff[DIM];

int read(){
  int nr = 0;

  while(!isdigit(buff[poz]))
    if(++poz == DIM){
      in.read(buff, DIM);
      poz = 0;
    }

  while(isdigit(buff[poz])){
    nr = nr * 10 + (buff[poz] - '0');

    if(++poz == DIM){
      in.read(buff, DIM);
      poz = 0;
    }
  }

  return nr;
}

bool ok(int x, int y){
  return((x & y) == 0);
}

int main()
{
  n = read();
  //in >> n;
  for(int i = 1; i <= n; i++)
    cost[i] = read();
    //in >> cost[i];
  p = read();
  //in >> p;
  for(int i = 1; i <= p; i++)
    v[i] = read();
    //in >> v[i];
  in.close();

  for(int i = 1; i <= n; i++)
    dp[0][i] = cost[i];

  for(int i = 0; i <= (1 << p) - 1; i++){
    for(int j = 1; j <= n; j++){
      //assert(dp[i][j] != 0);
      for(int k = 1; k <= p; k++){
        if(ok(i, 1 << (k - 1))){
          int i1, j1;
          i1 = i + (1 << (k - 1));
          j1 = j + v[k];
          if(j1 <= n && dp[i1][j1] < dp[i][j] + cost[j1]){
            dp[i1][j1] = dp[i][j] + cost[j1];
          }

          j1 = j - v[k];
          if(j1 >= 1 && dp[i1][j1] < dp[i][j] + cost[j1]){
            dp[i1][j1] = dp[i][j] + cost[j1];
          }
        }
      }
    }
  }

  /*
  for(int i = 0; i <= (1 << p); i++){
    for(int j = 1; j <= n; j++)
      out << dp[i][j] << ' ';
    out << '\n';
  }
  */

  for(int i = 1; i <= n; i++){
    sol = max(sol, dp[(1 << p) - 1][i]);
  }

  out << sol << '\n';
  return 0;
}