题目:在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果。
动态规划解法:
用动态规划从右边往左边,设数组diff[k]是k到最右端这个子数组中的要求的那个东西,min[k]是这个子数组中的最小值,求diff[k-1]只需要看k-1这个数与min[k]的差是否要大于diff[k],如果大就更新,不大就保持。即diff[k-1]=min{A[k-1]-min[k],diff[k-1]}.
#include <iostream>
int num[]={2, 4, 1, 16, 7, 5, 11, 9};
int main()
{
int min(0);
int diff[8];
diff[7]=0;
min=num[7];
for(int i=6;i>=0;i--){
if((num[i]-min)>diff[i+1]){
diff[i]=num[i]-min;
}
else{
diff[i]=diff[i+1];
}
if(min>num[i]){
min=num[i];/*更新最小值*/
}
}
std::cout<<diff[0];
getchar();
}
分治法:
#include <iostream>
int num[]={2, 4, 1, 16, 7, 5, 11, 9};
int diff_max;
int _find_diff(int left,int right,int& max,int &min);
int find_diff()
{
int max(0),min(0);
diff_max= _find_diff(0,7,max,min);
//return diff_max;
return 0;
}
int _find_diff(int left,int right,int& max,int &min)
{
if(left==right){
max=min=num[left];
return 0;
}
int left_max,right_max;
int left_min,right_min;
int middle=(left+right)/2;
int left_diff=_find_diff(left,middle,left_max,left_min);
int right_diff=_find_diff(middle+1,right,right_max,right_min);
int diff=left_diff>right_diff?left_diff:right_diff;
if((left_max-right_min)>diff){
diff=left_max-right_min;
}
max=left_max>right_max?left_max:right_max;
min=left_min<right_min?left_min:right_min;
return diff;
}
int main()
{
find_diff();
std::cout<<diff_max;
getchar();
}