algorithm – 我们如何有效地解决给定的场景?

我们有一个迷宫,我们需要尽可能多地访问房间.迷宫的特色是,一旦你进入任何一个房间,它只会带你到你移动方向有更高标签的房间. B和C决定向相反的方向移动,试图运气以最大化他们搜索的房间数量.(他们可以从任何房间开始,不必相同)

我们需要找出可以搜索的最大房间数.

1. Access to any room with a higher tag is allowed, not just adjacent rooms or the next room with a higher tag. 
2. Tags are unique. 

所以给出了输入:

12 11 10 1 2 3 4 13 6 7 8 5 9 
the answer is 12: (1,2,3,4,6,7,8,9) for B and (5,10,11,12) for C.

我想到使用最长的子序列从右到左然后从左边解决这个问题.上面两个子序列中的唯一元素的数量就是答案.

但我的逻辑似乎失败了,怎么办呢?

最佳答案 我的程序在下面计算搜索到的最大房间数.这具有O(n ^ 3)的时间复杂度.我修改了DP算法,用于计算在线可用的最长增长序列,以解决OP的问题.这也解决了OP对{1,4,6,2,5}等阵列的关注.我正确地将上一个示例的最大值设为5.所以,我使用@BeyelerStudios的想法,我们需要从左到右和从右到左计算最长的增长子序列.但是,有一个警告.如果我们计算从左到右的最大序列,则从右到左的序列应该在剩余的元素上.例:

对于数组{1,4,6,2,5}.如果选择的前向房间是{1,4,5},那么应该在左边的元素{6,2}上计算反向最长的增加序列.

以下是我的计划:

#include <iostream>
using namespace std;


// compute the max increasing sequence from right to left.
int r2lRooms (int arr[], int n) 
{

    int dp[n];
    int i =0, j = 0;
    int max = 0;

    for ( i = 0; i < n; i++ ) {
        dp[i] = 1;
    }

    for (i = n-2; i >= 0; i--) {
        for ( j = n-1; j > i; j-- ) {
            if ( arr[i] > arr[j] && dp[i] < dp[j] + 1) {
                dp[i] = dp[j] + 1;
            }
        }
    }

    for ( i = 0; i < n; i++ ) {
        if ( max < dp[i] ) {
            max = dp[i];
        }
    }
    return max;

}


// compute max rooms.
int maxRooms( int arr[], int n )
{

    int dp[n], revArray[n];
    int i =0, j = 0, k = 0;
    int currentMax = 0;
    int forwardMax = 0, reverseMax = 0;

    for ( i = 0; i < n; i++ ) {
        dp[i] = 1;
    }

    // First case is that except for first elem, all others are in revArray
    for (i=1; i < n; i++, k++) {
        revArray[k] = arr[i];
    }
    reverseMax = r2lRooms (revArray, k);
    forwardMax = 1;
    if (currentMax < (forwardMax + reverseMax)) {
        currentMax = forwardMax + reverseMax;
    }
    cout << "forwardmax revmax and currentmax are: " << forwardMax << " " << reverseMax << " " << currentMax << endl;
    cout << endl;

    for ( i = 1; i < n; i++ ) {
        k = 0;
        forwardMax = 1;
        reverseMax = 0;

        cout << "Forward elems for arr[" << i << "]=" << arr[i] << endl;

        for ( j = 0; j < i; j++ ) {
            if ( arr[i] > arr[j] && dp[i] < dp[j] + 1) {
                dp[i] = dp[j] + 1;
                forwardMax = dp[i]; 
                cout << arr[j] << " ";
            }
            else {
                // element was not in DP calculation, so put in revArray.
                revArray[k] = arr[j];
                k++;
            }
        }
        // copy the remaining elements in revArray.
        for ( j = i+1; j < n; j++ ) {
            revArray[k] = arr[j];
            k++;
        }
        cout << endl;
        reverseMax = r2lRooms (revArray, k);
        if (currentMax < (forwardMax + reverseMax)) {
            currentMax = forwardMax + reverseMax;
        }
        cout << "forwardmax revmax and currentmax are: " << forwardMax << " " <<  reverseMax << " " << currentMax << endl;
        cout << endl;
    }
    cout << " Max rooms searched " << currentMax << endl;
    return currentMax;
}

int main (void) {

    int arr[] = {12, 11, 10, 1, 2, 3, 4, 13, 6, 7, 8, 5, 9 };
    int size = sizeof(arr) / sizeof(int);

    cout << maxRooms (arr, size);


}
点赞