Laoj P1271 复制书稿
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 复制书稿的主要内容,如果未能解决你的问题,请参考以下文章