原创文章,转载请注明!
问题:给出一个数组,求出其中一个子集,使得子集中每个元素在原数组中两两都不相邻并使子集的和最大。
思路:先找到最优子结构,对于数组A[0...n],设r[i][j]为A[i][j]的不相邻最大子数组和,则有
r[i][j] =
max(A[i][j],0) i = j
max(r[i][k-1]+r[k-1][j]) i < j, k = i~j 注意k = i or j时,有点特殊,代码中可以看出来
#include <iostream>
#include <stdlib.h>
using namespace std;
#define MIN -1000000
int MaxSum(int *A, int len)
{
int **r = new int* [len];
for(int i = 0; i < len; i++)
r[i] = new int [len];
for (int i = 0; i < len; i++)
r[i][i] = A[i] > 0 ? A[i] : 0;
int l, i, j, k;
for (l = 2; l <= len; l++){
for(i = 0; i < len - l + 1; i++){
j = l + i - 1;
int temp = MIN;
for(k = i; k <= j; k++){
if (k == i)
temp = temp > r[k + 1][j] ? temp : r[k + 1][j];
else if (k == j)
temp = temp > r[i][k - 1] ? temp : r[i][k - 1];
else {
int q;
q = r[i][k - 1] + r[k + 1][j];
temp = temp > q ? temp : q;
}
}
r[i][j] = temp;
}
}
int maxsum = r[0][len - 1];
for (int n = 0; n < len; n++)
delete[] r[n];
delete[] r;
return maxsum;
}
int main()
{
int A[] = {-1,3,4};
int len = sizeof(A) / sizeof(int);
cout<<MaxSum(A, len)<<endl;
system("pause");
}