【dp】最小m段和问题

本文介绍了如何使用动态规划方法解决寻找数组中最小m段和的问题,详细阐述了算法思路与实现步骤,适用于优化编程任务中的求解效率。

问题描述:

 给定n个整数组成的序列,现在要求将序列分割为m段,每段子序列中的数在原序列中连续  排列。如何分割才能使这m段子序列的和的最大值达到最小?

编程任务:

 给定n个整数组成的序列,编程计算该序列的最优m段分割,使m段子序列的和的最大值达到  最小。

数据输入:

 输入的第1行中有2个正整数n和m。正整数n是序列的长度;正整数m是分割的断数。接下来  的一行中有n个整数。

结果输出:

 输出的第1行中的数是计算出的m段子序列的和的最大值的最小值。

样例:

 1 1
 10

10

核心思想:

 二分答案+贪心验证

var
 a:array[0..200]of longint;
 n,m,i,l,r,tot:longint;
function pd(x:longint):boolean;
var
 i,ans,sum:longint;
begin
 ans:=1;sum:=0;
 fori:=1 to n do
 begin
   ifa[i]>x then exit(false);
   ifsum+a[i]<=x then inc(sum,a[i])
   else
    begin
     inc(ans);
     sum:=a[i];
    end;
   ifans>m then exit(false);
 end;
 exit(true);
end;
begin
 assign(input,'p310.in');reset(input);
 assign(output,'p310.out');rewrite(output);
 readln(n,m);
 fori:=1 to n do
 begin
  read(a[i]);
  inc(tot,a[i]);
 end;
 l:=0;r:=tot;
 while l<r do
  ifpd((l+r)shr 1) then r:=(l+r)shr 1
  else l:=(l+r)shr 1+1;
 writeln(l);
 close(input);close(output);
end.
题目来源:《算法设计与分析》第三章动态规划

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值