2012-04-03 5 views
0

Я пишу программу, которая подсчитывает все двоичные деревья с n узлами и высотой k. Каждый узел имеет 0 или 2 детей. Программа работает, но я хотел добавить некоторую мемуаризацию, потому что ответ всегда один и тот же для некоторых конкретных n и k.C++ многомерный массив struct

Я мог бы создать многомерный массив пар, но у меня уже есть моя полезная структура. Как я могу объявить и использовать эту переменную mem. Я не нашел на этом хорошего ответа. Я понимаю указатели, но я бы предпочел метод без управления памятью.

Это упражнение из программы обучения USACO кстати.

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cmath> 
using namespace std; 

struct state { 
    int down, half; 
    state(int d, int h) : down(d), half(h) {} 
    int valid() { 
     return down != -1 && half != -1; 
    } 
}; 

state mem[200][100]; 

state cnt(int n, int k) 
{ 
    if (mem[n][k].valid()) 
     return mem[n][k]; 
    if (n == 1) 
     return state(k == 1, k != 1); 
    if (n > pow(2, k) - 1) 
     return state(-1, -1); 

    state total(0, 0); 
    for (int i = 1; i < n - 1; ++i) { 
     state left = cnt(i, k - 1); 
     state right = cnt(n - i - 1, k - 1); 

     if (left.valid() && right.valid()) { 
      total.down += left.down * right.down + 
          left.down * right.half + 
          left.half * right.down; 
      total.half += left.half * right.half; 
     } 
    } 

    return mem[n][k] = state(total.down % 9901, total.half % 9901); 
} 

int main() 
{ 
    ofstream fout ("nocows.out"); 
    ifstream fin ("nocows.in"); 

    int n, k; 
    fin >> n >> k; 

    for (int i = 0; i <= n; ++i) 
     for (int j = 0; j <= k; ++j) 
      mem[i][j] = state(-1, -1); 

    cout << cnt(n, k).down << endl; 

    return 0; 
} 

ответ

3

Вы можете использовать vector векторов:

std::vector<std::vector<state> > mem; 

Вы можете динамически добавлять к нему и не нужно беспокоиться о размере (хотя, если вы примерно знаете размер, вы можете предварительно выделить его во избежание изменения размера), а также очистка памяти автоматически - когда вектор выходит за рамки, его компоненты также будут удалены.

Ваш код не работает, потому что у вас нет конструктора по умолчанию для state.

Дело в том, что когда вы пишете state mem[200][100];, компилятор попытается создать объекты 100 * 200 state, но это невозможно. Для выполнения этой работы вам понадобится конструктор по умолчанию в state:

struct state { 
    state() : down(0), half(0) {} //default constructor 
    int down, half; 
    state(int d, int h) : down(d), half(h) {} 
    int valid() { 
     return down != -1 && half != -1; 
    } 
}; 
+0

Спасибо за оперативную реакцию. Это то, что мне нужно, но можете ли вы или кто-то еще объяснить, почему объявление массива не работает? – Jasper

+0

@ Джаспер объяснил в моем редактировании. –

Смежные вопросы