我们有一个迷宫,我们需要尽可能多地访问房间.迷宫的特色是,一旦你进入任何一个房间,它只会带你到你移动方向有更高标签的房间. 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);
}