首页 > 代码库 > codevs 3162 抄书问题
codevs 3162 抄书问题
3162 抄书问题
题目描述 Description
现在要把M本有顺序的书分给K个人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如不能把第一、第三、第四本数给同一个人抄写。现在请你设计一种方案,使得复制时间最短。复制时间为抄写页数最多的人用去的时间。
输入描述 Input Description
第一行两个整数M、K;(K<=M<=100)
第二行M个整数,第i个整数表示第i本书的页数。
输出描述 Output Description
共K行,每行两个正整数,第i行表示第i个人抄写的书的起始编号和终止编号。K行的起始编号应该从小到大排列,如果有多解,则尽可能让前面的人少抄写。
样例输入 Sample Input
9 3
1 2 3 4 5 6 7 8 9
样例输出 Sample Output
1 5
6 7
8 9
f[i][j] 表示抄到第j本书,用了i个人的时候,抄的最多的人最少抄多少
f[i][j]=min(max( f[k-1][j-1],sum[i]-sum[k])) sum[]是维护的前缀和
求出f[n][K-1]即n本书 分给K个人抄,抄的最多的人 最少抄多少,
题目要求靠前的人尽可能抄的少
那么 从后往前扫一遍,从后往前 分成一个个区间,每个区间不超过f[n][K-1]就行
#include<iostream>#include<cstring>using namespace std;int n,m,a[110],sum[110],dp[110][110],cnt;struct node{ int l,r;}s[110];int main(){ cin>>n>>m; if(n==0)return 0; memset(dp,127/3,sizeof(dp)); for(int i=1;i<=n;i++){ cin>>a[i];sum[i]=sum[i-1]+a[i]; dp[i][1]=sum[i]; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ for(int k=i;k>=1;k--){ dp[i][j]=min(dp[i][j],max(dp[k-1][j-1],sum[i]-sum[k-1])); } } } int ans=dp[n][m]; int sum=0,c=n; for(int i=n;i>=1;i--){ sum+=a[i]; if(sum>ans){ s[++cnt].l=i+1; s[cnt].r=c; c=i; sum=a[i]; } } if(cnt!=0){ cout<<1<<‘ ‘<<max(1,s[cnt].l-1)<<endl; for(int i=cnt;i>=1;i--){ cout<<s[i].l<<‘ ‘<<s[i].r<<endl; } } if(cnt==0){ cout<<1<<‘ ‘<<n; }}
codevs 3162 抄书问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。