演算法 最小M段和問題
阿新 • • 發佈:2019-01-31
題目
給定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;
}