最大值最小化(网易有道2013年校园招聘面试一面试题)

一道来自网易有道2013年校园招聘面试的题目,要求将包含n个正整数的序列分成m个连续子序列,目标是求所有子序列和的最大值的最小可能值。通过举例说明了问题并指出问题的本质是一个二维动态规划问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要。
当时都是通过招募抄写员来进行书本的录入和复制工作的, 假设现在要抄写m本书,编号为1,2,3...m, 每本书有1<=x<=100000页, 把这些书分配给k个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的。每个抄写员的速度是相同的,你的任务就是找到一个最佳的分配方案,使得所有书被抄完所用的时间最少。


输入:
输入可能包含多个测试样例。
第一行仅包含正整数 n,表示测试案例的个数。
对于每个测试案例,每个案例由两行组成,在第一行中,有两个整数m和 k, 1<=k<=m<=500。 在第二行中,有m个整数用空格分隔。 所有这些值都为正且小于100000。


输出:
对应每个测试案例,
输出一行数字,代表最佳的分配方案全部抄写完毕所需要的时间。


 


样例输入:
2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100
样例输出:
1700

200

这道题目跟另一道常见的题目类似

问题描述:

把一个包含n个正整数的序列划分成m个连续的子序列。设第i个序列的各数之和为S(i),求所有S(i)的最大值最小是多少?

例如序列1 2 3 2 5 4划分为3个子序列的最优方案为 1 2 3 | 2 5 | 4,其中S(1),S(2),S(3)分别为6,7,4,那么最大值为7;

如果划分为 1 2 | 3 2 | 5 4,则最大值为9,不是最小。

可以采用 http://blog.youkuaiyun.com/nanjunxiao/article/details/8145971所描述的方法,但是在面试那种紧张的环境下还是走一些正常路,贪心加二分的思想有一定的技巧性。所以我想直接通过动态规划去解,这样更走寻常路。也解释了下面评论给出的疑问,为什么不用贪心加二分

可以看出来这是一道二维动态规划的问题

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <deque>

using namespace std;
 //m书的本书,k抄写员的个数
int dp[505][505];
int data[505]={100, 200, 300, 400, 500, 600, 700, 800, 900}; //每本书的页数

#define max(a, b) (a > b ? a : b)

#define INF 100000000

int GetMax(int m , int k){
    int i,j,l,jj,sum;
    dp[0][1] = 0;
    for (j = 1; j <= m; j ++)
        dp[j][1] = dp[j - 1][1] + data[j];
    for (l = 2; l <= k; l ++){
        for (j = l; j <= m - (k - l); j ++){
            sum = 0;
            dp[j][l] = INF;
            for (jj = j; jj >= l; jj --){
                sum += data[jj];
                if (max(dp[jj - 1][l - 1], sum) < dp[j][l])
                    dp[j][l] = max(dp[jj - 1][l - 1], sum);
            }
        }
    }    
    return dp[m][k];
}

int main(void)
{
    cout<<GetMax(9,3)<<endl;
    system("pause");
    return EXIT_SUCCESS;
}





评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值