算法 最小M段和问题

来源:互联网 发布:剑三明教正太捏脸数据 编辑:程序博客网 时间:2024/06/05 02:45

题目

给定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 100int 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;} 
0 0
原创粉丝点击