Найдите подмассив m * m (2 <= m <n), имеющий наибольшую сумму; из массива n * n int (с + ve, -ve, 0s)

0

Я написал решение для вышеупомянутой проблемы, но кто-то может предложить оптимизированный способ. Я прошел через массив для count (от 2 до n), где count находит подмассивы подсчета количества * count.

int n = 5;      //Size of array, you may take a dynamic array as well
int a[5][5] = {{1,2,3,4,5},{2,4,7,-2,1},{4,3,9,9,1},{5,2,6,8,0},{5,4,3,2,1}};
int max = 0;
int **tempStore, size;

for(int count = 2; count < n; count++)
{
    for(int i = 0; i <= (n-count); i++)
    {
        for(int j = 0; j <= (n-count); j++)
        {
            int **temp = new int*[count]; 
            for(int i = 0; i < count; ++i) {
                temp[i] = new int[count];
            }

            for(int k = 0; k < count; k++)
            {
                for(int l = 0; l <count; l++)
                {
                    temp[k][l] = a[i+k][j+l];
                }
            }
            //printing fetched array
            int sum = 0;
            for(int k = 0; k < count; k++)
            {
                for(int l = 0; l <count; l++)
                {
                    sum += temp[k][l];
                    cout<<temp[k][l]<<" ";
                }cout<<endl;
            }cout<<"Sum = "<<sum<<endl;
            if(sum > max)
            {
                max = sum;
                size = count;
                tempStore = new int*[count]; 
                for(int i = 0; i < count; ++i) {
                    tempStore[i] = new int[count];
                }
                //Locking the max sum array
                for(int k = 0; k < count; k++)
                {
                    for(int l = 0; l <count; l++)
                    {
                        tempStore[k][l] = temp[k][l];
                    }
                }
            }
            //printing finished
            cout<<"------------------\n";
            //Clear temp memory
            for(int i = 0; i < size; ++i) {
                delete[] temp[i];
            }
            delete[] temp;
        }
    }
}

cout<<"Max sum is = "<<max<<endl;
for(int k = 0; k < size; k++)
{
    for(int l = 0; l <size; l++)
    {
        cout<<tempStore[k][l]<<" ";
    }cout<<endl;
}cout<<"-------------------------";

//Clear tempStore memory
for(int i = 0; i < size; ++i) {
    delete[] tempStore[i];
    }
delete[] tempStore;

Пример:

1 2 3 4 5

2 4 7 -2 1

4 3 9 9 1

5 2 6 8 0

5 4 3 2 1

Выход: Максимальная сумма = 71

2 4 7 -2

4 3 9 9

5 2 6 8

5 4 3 2

  • 6
    C или C ++? Выбери один.
  • 1
    Я думаю, ваш вопрос больше подходит для Code Review
Показать ещё 5 комментариев
Теги:
arrays

3 ответа

0

С суммарной суммой вы можете вычислить частичную сумму в постоянное время

std::vector<std::vector<int>>
compute_cumulative(const std::vector<std::vector<int>>& m)
{
    std::vector<std::vector<int>> res(m.size() + 1, std::vector<int>(m.size() + 1));

    for (std::size_t i = 0; i != m.size(); ++i) {
        for (std::size_t j = 0; j != m.size(); ++j) {
            res[i + 1][j + 1] = m[i][j] - res[i][j]
                        + res[i + 1][j] + res[i][j + 1];
        }
    }
    return res;
}

int compute_partial_sum(const std::vector<std::vector<int>>& cumulative, std::size_t i, std::size_t j, std::size_t size)
{
    return cumulative[i][j] + cumulative[i + size][j + size]
           - cumulative[i][j + size] - cumulative[i + size][j];

}

живой пример

0

Попробуйте это (используя наивный подход, будет легче получить идею):

#include <iostream> 
#include<vector>
using namespace std; 
int main( )
{ 
    int n = 5; //Size of array, you may take a dynamic array as well
    int a[5][5] = 
      {{2,1,8,9,0},{2,4,7,-2,1},{5,4,3,2,1},{3,4,9,9,2},{5,2,6,8,0}};
    int sum, partsum;
    int i, j, k, m;
    sum = -999999; // presume minimum part sum 
    for (i = 0; i < n; i++) {
        partsum = 0;
        m = sizeof(a[i])/sizeof(int);
        for (j = 0; j < m; j++) {
            partsum += a[i][j];
        }
        if (partsum > sum) {
            k = i;
            sum = partsum;
        }
    }
    // print subarray having largest sum
    m = sizeof(a[k])/sizeof(int); // m needs to be recomputed
    for (j = 0; j < m - 1; j++) {
        cout << a[k][j] << ", ";
    }
    cout << a[k][m - 1] <<"\nmax part sum = " << sum << endl;
    return 0;
}
  • 0
    Спасибо за ответ, но он не дает мне желаемого результата. Я добавил пример в вопрос сейчас.
  • 0
    Отредактировано, была одна проблема, m нужно пересчитать перед последним циклом
0

Это проблема, которую лучше всего решить с помощью Dynamic Programming (DP) или memoization.

Предполагая, что n значительно велико, вы обнаружите, что пересчет суммы всех возможных комбинаций матрицы займет слишком много времени, поэтому, если вы сможете повторно использовать предыдущие вычисления, которые сделают все намного быстрее.

Идея состоит в том, чтобы начать с меньших матриц и вычислить сумму более крупного, повторно использующего предварительно рассчитанное значение меньших.

long long *sub_solutions = new long long[n*n*m];

#define at(r,c,i) sub_solutions[((i)*n + (r))*n + (c)]

// Winner:
unsigned int w_row = 0, w_col = 0, w_size = 0;

// Fill first layer:
for ( int row = 0; row < n; row++) {
    for (int col = 0; col < n; col++) {
        at(r, c, 0) = data[r][c];
        if (data[r][c] > data[w_row][w_col]) { 
            w_row = r;
            w_col = c;
        }           
    }
}

// Fill remaining layers.
for ( int size = 1; size < m; size++) {
    for ( int row = 0; row < n-size; row++) {
        for (int col = 0; col < n-size; col++) {
            long long sum = data[row+size][col+size];
            for (int i = 0; i < size; i++) {
                sum += data[row+size][col+i];
                sum += data[row+i][col+size];
            }
            sum += at(row, col, size-1); // Reuse previous solution.
            at(row, col, size) = sum;
            if (sum > at(w_row, w_col, w_size)) { // Could optimize this part if you only need the sum.
                w_row = row;
                w_col = col;
                w_size = size;
            }
        }
    }
}

// The largest sum is of the sub_matrix starting a w_row, w_col, and has dimensions w_size+1.
long long largest = at(w_row, w_col, w_size);

delete [] sub_solutions;

Этот алгоритм имеет сложность: O(n*n*m*m) или более точно: 0.5*n*(n-1)*m*(m-1). (Теперь я не проверял это, поэтому, пожалуйста, дайте мне знать, есть ли какие-либо ошибки.)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню