首页 > 代码库 > Laoj P1271 复制书稿
Laoj P1271 复制书稿
问题背景
|
动态规划入门-第20题
|
试题描述
|
现在要把m本有顺序的书分给k人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如不能把第一、第三、第四本书给同一个人抄写。
现在请你设计一种方案,使得复制时间最短。复制时间为抄写页数最多的人用去的时间。 |
输入格式
|
第一行两个整数m,k;(k≤m≤500)
第二行m个整数,第i个整数表示第i本书的页数。 |
输出格式
|
共k行,每行两个整数,第i行表示第i个人抄写的书的起始编号和终止编号。k行的起始编号应该从小到大排列,如果有多解,则尽可能让前面的人少抄写。
|
输入示例
|
9 3
1 2 3 4 5 6 7 8 9 |
输出示例
|
1 5
6 7 8 9 |
【分析】
典型的区间dp,三层循环轻松解决。
需要注意的是输出,要求前面的人尽量少抄于是从后往前列举,运用了贪心的思想。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int m, k, a[505], sum[505], dp[505][505], maxx, b[505], c[505][505]; 5 6 void init() { 7 cin >> m >> k; 8 for (int i=1;i<=m;++i) { 9 cin >> a[i]; 10 sum[i]=sum[i-1]+a[i]; 11 } 12 } 13 14 void sovle() { 15 for (int i=1;i<=k;++i) { 16 for (int j=i;j<=m;++j) { 17 dp[i][j]=0x7fffffff; 18 for (int t=i-1;t<j;++t) 19 if (i==1) 20 dp[i][j]=sum[j]; 21 else 22 dp[i][j]=min(dp[i][j], max(dp[i-1][t], sum[j]-sum[t])); 23 } 24 } 25 maxx=dp[k][m]; 26 int t=k; 27 for (int i=m;i>0;--i) { 28 if (a[i]+b[t]>maxx) 29 t--; 30 b[t]+=a[i], c[t][++c[t][0]]=i; 31 } 32 for (int i=1;i<=k;++i) 33 cout << c[i][c[i][0]] << " " << c[i][1] << endl; 34 } 35 36 int main() { 37 init(); 38 sovle(); 39 }
Laoj P1271 复制书稿
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。