#include <iostream>
#include <stdio.h>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <math.h>
#include "MaxSubarray.h"
/************************************************************************/
/* 分治法
最大和子数组有三种情况:
1)A[1...mid]
2)A[mid+1...N]
3)A[i..mid..j]
/************************************************************************/
int Find_Max_Crossing_Subarray (int a[],int low, int mid, int high)
{
int left_sum = INT_MIN;
int right_sum = INT_MIN;
int max_left = -1, max_right = -1;
int sum = 0;
for ( int i = mid; i >= low; i-- )
{
sum += a [i];
if (sum > left_sum)
{
left_sum = sum;
max_left = i;
}
}
sum = 0;
for ( int j = mid + 1; j <= high; j++ )
{
sum += a [j];
if (sum>right_sum)
{
right_sum = sum;
max_right = j;
}
}
std::cout << left_sum + right_sum << std::endl;;
return ( left_sum + right_sum );
}
int Find_Maximum_Subarrary ( int a[], int low, int hight )
{
if (low==hight)
{
std::cout << a [low]<< std::endl;
return a [low];
}
else
{
int mid = ( low + hight ) / 2;
int leftsum = Find_Maximum_Subarrary ( a, low, mid );
int rightsum = Find_Maximum_Subarrary ( a, mid+1, hight );
int crosssum = Find_Max_Crossing_Subarray ( a, low, mid, hight );
if (leftsum>=rightsum && leftsum > crosssum)
{
return leftsum;
}
else if ( rightsum >= leftsum && rightsum > crosssum )
{
return rightsum;
}
else
return crosssum;
}
}
/************************************************************************/
/* 区间法 不能每次都求出最大子数组?? 有个条件不对
求A[1...j+1]的最大和子数组,有两种情况:
1)A[1...j]的最大和子数组
2)某个A[i...j+1]的最大和子数组
/************************************************************************/
void MaxSubArraySum_Greedy ( int arr[], std::vector<int> &subarr, int len )
{
if ( len == 0 )
{
return;
}
int nmax = INT_MIN;
int low = 0, high = 0;
int cur = 0; // 一个指针更新子数组的左区间
int nsum = 0;
for ( int i = 0; i < len;i++ )
{
nsum += arr [i];
if ( nsum > nmax ) // 当和在增加时,区间向右增大
{
nmax = nsum;
low = cur;
high = i;
}
if ( nsum<0 ) // 条件不对 当和小于零时,区间向左减小,当和在增加时,区间向右增大
{
cur += 1;
nsum = 0;
}
}
for ( int i= low; i <= high; i++ )
{
subarr.push_back ( arr [i] );
}
}
/************************************************************************/
/* 动态规划(对应着上面的贪心法看,略有不同)
求A[1...j+1]的最大和子数组,有两种情况:
1)A[1...j]+A[j+1]的最大和子数组
2)A[j+1]
dp递推式:
sum[j+1] = max(sum[j] + A[j+1], A[j+1])
/***************************************************************/
int MaxSubArraySum_dp ( int arr[], int len )
{
if (len <=0)
{
exit ( -1 );
}
int nmax = INT_MIN;
int sum = 0;
for ( int i = 0; i < len; i++ )
{
if ( sum >= 0 )
sum += arr [i];
else
sum = arr [i];
if (sum > nmax)
{
nmax = sum;
}
}
return nmax;
}
// 钢条
#define get_max(a,b) (a>=b)?a:b
// 带备忘,自顶向下
int Memoized_Cut_rog_Aux ( int p[], int nlength, int r[] );
int Memoized_Cut_rog ( int p[], int nlength )
{
int* r = new int[nlength];
memset ( r, INT_MIN, nlength );
return Memoized_Cut_rog_Aux ( p, nlength, r );
}
int Memoized_Cut_rog_Aux ( int p[], int nlength, int r[] )
{
int result = INT_MIN;
if ( r [nlength] >= 0 )
{
return r [nlength];
}
if (nlength==0)
{
result = 0;
}
for ( int i = 1; i <= nlength; i++ )
{
result = get_max ( result, p [i - 1] + Memoized_Cut_rog_Aux ( p, nlength - i, r ) );
}
r [nlength] = result;
return result;
}
// 无备忘,很慢
int solution (int p[], int nlength )
{
if (nlength==0)
{
return 0;
}
int result = INT_MIN;
for ( int i = 1; i <= nlength; i++ )
{
result = get_max ( result, p [i - 1] + solution ( p,nlength - i ) );
}
return result;
}
// 背包问题 带备忘,计算耗时短
int GetMaxValueOfWeight_Aux ( int r[], int v[], int w[], int nsize, int wr );
int GetMaxValueOfWeight ( int v[], int w[],int nsize,int wr )
{
int *r = new int [wr];
memset ( r, 0, wr );
for ( int i = 1; i <= wr; i++ )
{
return GetMaxValueOfWeight_Aux ( r, v, w, nsize,wr );
}
}
int GetMaxValueOfWeight_Aux ( int r[], int v[], int w[], int nsize, int wr )
{
int result = INT_MIN;
if (r[wr]>=0)
return r [wr];
if (wr==0)
result = 0;
for ( int i = 1; i <= wr; i++ )
{
int preresult = 0;
for ( int j = 0; j < nsize; j++ )
{
if ( w [j] == wr ) // 查找当前存在的 重量
{
// 保存 重量相同时所有的价格
if ( v [j] >= result ) //
result = v [j];
}
if ( w [j] == i ) // 剩下另一部分的长度
{
if ( v [j] >= preresult )
preresult = v [j];
}
}
result = get_max ( result, preresult + GetMaxValueOfWeight_Aux ( r, v, w, nsize, wr - i ) );
}
r [wr] = result;
return result;
}
int main ()
{
// int a[] = { 8,1, -2, 3, 10, -4, 7, 2, -5 };
// std::cout << Find_Maximum_Subarrary ( a, 0, 9 ) << " " << std::endl;
//
// std::vector<int > subarr;
// MaxSubArraySum_Greedy ( a, subarr, 9 );
// for ( int i = 0; i < subarr.size (); i++ )
// {
// std::cout << subarr.at ( i ) << " " << std::endl;
// }
//
// std::cout << MaxSubArraySum_dp ( a, 9 ) << std::endl;
// int prices[] = { 1, 5, 8, 9, 10, 17, 17, 20, 24, 30,
// 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 ,
// 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 };
//
// for ( int i = 1; i <= 33; i++ )
// {
// //std::cout << i << " " << solution ( prices, i ) << std::endl;
// // std::cout << i << " " << BOTTOM_UP_CUT_ROD ( prices, i ) << std::endl;
// std::cout << i << " " << Memoized_Cut_rog ( prices, i ) << std::endl;
// }
int Weight[] = { 0,2, 2, 6, 5, 4 }; //物品的重量
int Value[] = {0,6, 3, 5, 4, 6 }; //物品的价值
for ( size_t i = 1; i <= 10; i++ )
{
std::cout << i << " " << GetMaxValueOfWeight (Value,Weight,6,i ) << std::endl;
}
system ( "pause" );
return 0;
}