1. 程式人生 > >演算法 最小M段和問題

演算法 最小M段和問題

題目

給定n個整陣列成的序列,現在要求將序列分割為m段,每段子序列中的數在原序列中連續排列。
如何分割才能使這m段子序列的和的最大值達到最小?

分析

動態規劃。
方程:
f[i][j] = min{max{f[i][1]-f[k][1],f[k][j-1]}},其中max:1<=k<=i,在k範圍內,兩部分取最大最小值。
f[i][j]表示前i個數據分成j段得最大最小值。
f[i][1]-fa[k][1]表示k~i的值。
f[k][j-1]表示前k個數據分成j-1段得最大最小值。

#include <stdio.h>
#include <stdlib.h>
#define MAX 100 int X = 100000; int a[MAX]={0,1,2,3,4,5};//輸入5個數 int f[MAX][MAX]; int getmax(int a, int b){ return a>b?a:b; } int suanfa(int n, int m){//返回總長度為n的序列的劃分為m段子序列後和的最大值的最小值 int i,j,k,temp,min; f[0][1]=0; for(i=1; i<=n; i++) //f[i][1]前i個數據分成一段得最大最小值。 f[i][1]=f[i-1][1]+a[i];//前i-1段+當前=前i段
for(i=2; i<=n; i++){ for(j=2; j<=m; j++){ for(k=1,temp=X; k<i; k++){ min=getmax(f[i][1]-f[k][1],f[k][j-1]);//比較得到大的 if(min<temp) temp=min; } f[i][j]=temp; } } return f[n][m]; } int
main(){ int n=5;//序列長度 int m=2;//分割的段數 printf("%d\n",suanfa(n,m)); return 0; }