問題描述:
程式設計開發練習題:最大子段和。給定n個整數(可能為負數)組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為: max,1<=i<=j<=n。
自上而下的分治演算法:
將序列a[1:n]分解為長度相等的2段a[1:n/2],和a[n/2+1, n],分別求出這2個字段的和,與a[1:n]的最大欄位和相比,有三種情況會出現:
1. a[1:n/2]與a[1:n]的最大子段和相同 <=> 最大欄位在前半部分
2. a[n/2+1, n]與a[1:n]的最大子段和相同 <=> 最大子段在後半部分
3. a[1:n]的最大子段和為越過中點n/2,這種情況下a[n/2]和a[n/2+1]在最優子串行中,在[i,n/2]找到最大值s1,在[n/2+1,j]中找到最大值s1,所求最優值為s1+s2,最優序列為i->j。
源程式**:
#include
#include
#include
#define max 10010
using namespace std;
int maxsubsum(int *a, int left, int right)
/*第三種情況下的右方最大子段和*/
int s2=0;
int rights=0;
for(int i=mid+1; i<=right; i++)
sum = s1+s2;
if(sum>num;
cout<>sequence[i];
}cout動態規劃演算法:根據分治法,分析左右子段s1,s2與原序列最優值之間的關係,需要知道段與子段之間最優值的遞迴關係。對所求的最大子段有如下關係:
二維表示的左端i,右端j轉化為一維的表示b[j],左端j,利於降低演算法複雜性。
根據b[j]的定義,是0~j這個序列的最大子段和,從而有如下推論
當b[j-1]>0時,b[j]=b[j-1]+a[j],
當b[j-1]<=0時,b[j] = a[j];
綜上所述得到遞迴方程:
源程式**:#include
#include
#include
#define maxn 5000
using namespace std;
file *fp, *fp1;
int a[maxn], b[maxn];
int maxsum(int n, int a, int *l, int *r)
else
if(bb>sum)
}return sum;
}int main()
while(!feof(fp1))
cout<
程式設計開發練習題
急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙個充滿了變數的生命過程,天災 人禍 病痛是我們生...
程式設計練習題
程式student create student studs,int n student 是乙個結構型別,包含姓名 成績和指標域。studs 陣列中儲存了n個 student 記錄。create 函式的功能是編寫根據 studs 陣列建立乙個鍊錶,鍊錶中結點按成績降序排列,函式返回煉表頭指標。inc...
程式設計練習題 求解全排列求最大子陣列之和(Java)
給定乙個整數陣列,找到乙個具有最大和的子陣列,返回其最大和。樣例給出陣列 2,2,3,4,1,2,1,5,3 符合要求的子陣列為 4,1,2,1 其最大和為6 1 找出子陣列的最左端點 for i 1 to n 2 找出子陣列的最右端點 for j i to n 3 求和,找出最大值 sum a i...