Problem p00245 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Cell {
  Cell(int arg_row, int arg_col) {
    row = arg_row;
    col = arg_col;
  }
  bool operator<(const struct Cell &arg) const {
    if (row != arg.row) {
      return row < arg.row;
    } else {
      return col < arg.col;
    }
  };
  int row, col;
};

struct Info {
  int discount, start, end;
};

struct Data {
  Data(int arg_row, int arg_col, int arg_total_dist) {
    row = arg_row;
    col = arg_col;
    total_dist = arg_total_dist;
  }

  int row, col, total_dist;
};

struct SALE {
  SALE() { state = time = row = col = sum_discount = 0; }

  SALE(int arg_state, int arg_time, int arg_row, int arg_col,
       int arg_sum_discount) {
    state = arg_state;
    time = arg_time;
    row = arg_row;
    col = arg_col;
    sum_discount = arg_sum_discount;
  }

  int state, time, row, col, sum_discount;
};

int W, H;
int POW[11];
int dp[1024][20][20];
Info info[10];
bool is_sale[10];
int diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};

char base_map[20][21];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

void func() {

  char buf[2];

  int start_row, start_col;

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      scanf("%s", buf);
      base_map[row][col] = buf[0];
      if (buf[0] == 'P') {
        base_map[row][col] = '.';
        start_row = row;
        start_col = col;
      }
    }
  }

  int N;
  scanf("%d", &N);

  int g, d, s, e;

  for (int i = 0; i < 10; i++)
    is_sale[i] = false;

  for (int loop = 0; loop < N; loop++) {
    scanf("%d %d %d %d", &g, &d, &s, &e);

    info[g].discount = d;
    info[g].start = s;
    info[g].end = e;

    is_sale[g] = true;
  }

  int limit = POW[10];

  for (int state = 0; state < limit; state++) {
    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++) {
        // dp[state][row][col] = BIG_NUM; //????????????????????????
        dp[state][row][col] = -1;
      }
    }
  }

  queue<SALE> Q;

  dp[0][start_row][start_col] = 0;

  SALE first;
  first.row = start_row;
  first.col = start_col;
  first.state = 0;
  first.sum_discount = 0;
  first.time = 0;

  Q.push(first);
  int max_value = 0;

  while (!Q.empty()) {

    // printf("row:%d col:%d time:%d sum:%d
    // state:%d\\n",Q.front().row,Q.front().col,Q.front().time,Q.front().sum_discount,Q.front().state);

    max_value = max(max_value, Q.front().sum_discount);

    for (int i = 0; i < 4; i++) {
      int adj_row = Q.front().row + diff_row[i];
      int adj_col = Q.front().col + diff_col[i];

      if (rangeCheck(adj_row, adj_col) == false)
        continue;

      if (base_map[adj_row][adj_col] == '.') { //???????????´???

        if (dp[Q.front().state][adj_row][adj_col] < Q.front().sum_discount) {
          dp[Q.front().state][adj_row][adj_col] = Q.front().sum_discount;

          SALE next_sale;
          next_sale.row = adj_row;
          next_sale.col = adj_col;
          next_sale.state = Q.front().state;
          next_sale.sum_discount = Q.front().sum_discount;
          next_sale.time = Q.front().time + 1;

          // printf("?????? row:%d col:%d?????????%d
          // state:%d??§????§?\\n",adj_row,adj_col,Q.front().time+1,Q.front().state);

          Q.push(next_sale);
        }
      } else if (base_map[adj_row][adj_col] >= '0' &&
                 base_map[adj_row][adj_col] <= '9') {

        int adj_item = base_map[adj_row][adj_col] - '0';

        if (Q.front().state & (1 << adj_item))
          continue;
        if (is_sale[adj_item] == false)
          continue;

        int next_state = Q.front().state + POW[adj_item];

        if (Q.front().time >= info[adj_item].start &&
            Q.front().time <
                info[adj_item]
                    .end) { //??????????§??????????????????§?????????????????????

          if (dp[next_state][Q.front().row][Q.front().col] <
              Q.front().sum_discount + info[adj_item].discount) {

            dp[next_state][Q.front().row][Q.front().col] =
                Q.front().sum_discount + info[adj_item].discount;

            SALE next_sale;
            next_sale.row = Q.front().row;
            next_sale.col = Q.front().col;
            next_sale.state = next_state;
            next_sale.sum_discount =
                Q.front().sum_discount + info[adj_item].discount;
            next_sale.time = Q.front().time;

            // printf("?????? row:%d col:%d?????????%d
            // state:%d??§????§?\\n",adj_row,adj_col,Q.front().time+1,Q.front().state);

            Q.push(next_sale);
          }

        } else if (Q.front().time < info[adj_item].start) {

          /*if(dp[next_state][Q.front().row][Q.front().col] <
             Q.front().sum_discount+info[adj_item].discount){

                  dp[next_state][Q.front().row][Q.front().col] =
             Q.front().sum_discount+info[adj_item].discount;*/
          SALE next_sale;
          next_sale.row = Q.front().row;
          next_sale.col = Q.front().col;
          next_sale.state = Q.front().state;
          next_sale.sum_discount = Q.front().sum_discount;
          next_sale.time = info[adj_item].start;

          // printf("?????\\?????? row:%d col:%d?????????%d
          // state:%d??§????§?\\n",adj_row,adj_col,Q.front().time+1,Q.front().state);

          Q.push(next_sale);
          //}
        }
      }
    }
    Q.pop();
  }

  printf("%d\\n", max_value);
}

int main() {

  for (int i = 0; i <= 10; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d %d", &W, &H);
    if (W == 0 && H == 0)
      break;

    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Cell {
  Cell(int arg_row, int arg_col) {
    row = arg_row;
    col = arg_col;
  }
  bool operator<(const struct Cell &arg) const {
    if (row != arg.row) {
      return row < arg.row;
    } else {
      return col < arg.col;
    }
  };
  int row, col;
};

struct Info {
  int discount, start, end;
};

struct Data {
  Data(int arg_row, int arg_col, int arg_total_dist) {
    row = arg_row;
    col = arg_col;
    total_dist = arg_total_dist;
  }

  int row, col, total_dist;
};

struct SALE {
  SALE() { state = time = row = col = sum_discount = 0; }

  SALE(int arg_state, int arg_time, int arg_row, int arg_col,
       int arg_sum_discount) {
    state = arg_state;
    time = arg_time;
    row = arg_row;
    col = arg_col;
    sum_discount = arg_sum_discount;
  }
  bool operator<(const struct SALE &arg) const {
    if (time != arg.time) {
      return time > arg.time;
    } else {
      return sum_discount < arg.sum_discount;
    }
  };

  void copyArray(SALE arg) {
    for (int i = 0; i < 10; i++) {
      visited[i] = arg.visited[i];
    }
  }

  int state, time, row, col, sum_discount;
  bool visited[10];
};

int W, H, item_num, limit;
int number[10], rev_number[10];
int POW[10];
int dp[1024][20][20];
Info info[10];
bool is_sale[10];
int diff_row[4] = {-1, 0, 0, 1}, diff_col[4] = {0, -1, 1, 0};

char base_map[20][21];

bool rangeCheck(int row, int col) {
  if (row >= 0 && row <= H - 1 && col >= 0 && col <= W - 1)
    return true;
  else {
    return false;
  }
}

void func() {

  char buf[2];

  int index = 0;

  int start_row, start_col;

  item_num = 0;

  for (int i = 0; i < 10; i++) {
    number[i] = -1;
  }

  for (int row = 0; row < H; row++) {
    for (int col = 0; col < W; col++) {
      scanf("%s", buf);
      base_map[row][col] = buf[0];
      if (buf[0] >= '0' && buf[0] <= '9') {

        if (number[buf[0] - '0'] == -1) {
          number[buf[0] - '0'] = index;
          rev_number[index] = buf[0] - '0';
          item_num++;
          index++;
        }
      } else if (buf[0] == 'P') {
        base_map[row][col] = '.';
        start_row = row;
        start_col = col;
      }
    }
  }

  int N;
  scanf("%d", &N);

  int g, d, s, e;

  for (int i = 0; i < 10; i++)
    is_sale[i] = false;

  for (int loop = 0; loop < N; loop++) {
    scanf("%d %d %d %d", &g, &d, &s, &e);

    info[number[g]].discount = d;
    info[number[g]].start = s;
    info[number[g]].end = e;

    is_sale[number[g]] = true;
  }

  /*for(int i = 0; i < item_num; i++){

          printf("??????%d(??????%d) ",i,rev_number[i]);
          if(is_sale[i]){
                  printf("???????????????\\n");
                  printf("dis:%d start:%d
  end:%d\\n",info[i].discount,info[i].start,info[i].end); }else{
                  printf("?????????????????????\\n");
          }

  }
*/

  limit = POW[item_num];

  for (int state = 0; state < limit; state++) {
    for (int row = 0; row < H; row++) {
      for (int col = 0; col < W; col++) {
        dp[state][row][col] = BIG_NUM; //????????????????????????
      }
    }
  }

  priority_queue<SALE> Q;

  dp[0][start_row][start_col] = 0;

  SALE first;
  first.row = start_row;
  first.col = start_col;
  first.state = 0;
  first.sum_discount = 0;
  first.time = 0;
  for (int i = 0; i < item_num; i++)
    first.visited[i] = false;

  Q.push(first);
  int max_value = 0;

  while (!Q.empty()) {

    max_value = max(max_value, Q.top().sum_discount);

    if (Q.top().state == limit - 1) {
      Q.pop();
    } else {

      for (int i = 0; i < 4; i++) {
        int adj_row = Q.top().row + diff_row[i];
        int adj_col = Q.top().col + diff_col[i];

        if (rangeCheck(adj_row, adj_col) == false)
          continue;

        if (base_map[adj_row][adj_col] == '.') { //???????????´???

          if (dp[Q.top().state][adj_row][adj_col] > Q.top().time + 1) {
            dp[Q.top().state][adj_row][adj_col] = Q.top().time + 1;

            SALE next_sale;
            next_sale.row = adj_row;
            next_sale.col = adj_col;
            next_sale.state = Q.top().state;
            next_sale.sum_discount = Q.top().sum_discount;
            next_sale.time = Q.top().time + 1;
            next_sale.copyArray(Q.top());

            Q.push(next_sale);
          }
        } else {

          // printf("row:%d col:%d time:%d
          // state:%d\\n",Q.top().row,Q.top().col,Q.top().time,Q.top().state);

          int adj_item = number[base_map[adj_row][adj_col] - '0'];

          if (Q.top().visited[adj_item] == true || is_sale[adj_item] == false ||
              info[adj_item].end < Q.top().time)
            continue;

          int next_state = Q.top().state + POW[adj_item];

          if (Q.top().time >= info[adj_item].start &&
              Q.top().time <=
                  info[adj_item]
                      .end) { //??????????§??????????????????§?????????????????????

            if (dp[next_state][Q.top().row][Q.top().col] > Q.top().time) {

              dp[next_state][Q.top().row][Q.top().col] = Q.top().time;
              SALE next_sale;
              next_sale.row = Q.top().row;
              next_sale.col = Q.top().col;
              next_sale.state = next_state;
              next_sale.sum_discount =
                  Q.top().sum_discount + info[adj_item].discount;
              next_sale.time = Q.top().time;
              next_sale.copyArray(Q.top());
              next_sale.visited[adj_item] = true;

              Q.push(next_sale);
            }

          } else if (Q.top().time < info[adj_item].start) { //??????

            SALE next_sale;
            next_sale.row = Q.top().row;
            next_sale.col = Q.top().col;
            next_sale.state = Q.top().state;
            next_sale.sum_discount = Q.top().sum_discount;
            next_sale.time = Q.top().time + 1;
            next_sale.copyArray(Q.top());

            Q.push(next_sale);
          }
        }
      }
      Q.pop();
    }
  }

  printf("%d\\n", max_value);
}

int main() {

  for (int i = 0; i < 10; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d %d", &W, &H);
    if (W == 0 && H == 0)
      break;

    func();
  }

  return 0;
}