資訊學奧賽一本通1278:複製書稿(evd)
阿新 • • 發佈:2020-12-16
【題目描述】
現在要把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的經典模型。課本上說的已經夠清楚了,不再贅述。
【AC程式碼】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=505;
const int INF=0x7fffffff;
int m,k,a[N],d[N],f[N][N];
int pri(int i,int j)
{
int t,x;
if(j==0) return 0;
if(j==1)
{
cout<<1 <<" "<<i<<endl;
return 0;
}
t=i;
x=a[i];
while(x+a[t-1]<=f[k][m])
{
x=x+a[t-1];
t--;
}
pri(t-1,j-1);
cout<<t<<" "<<i<<endl;
}
int main()
{
cin>>m>>k;
for(int i=1;i<=m;i++)
{
cin>>a[i];
d[i]=d[ i-1]+a[i];
f[1][i]=d[i];
}
for(int i=2;i<=k;i++) for(int j=1;j<=m;j++) f[i][j]=INF;
for(int i=2;i<=k;i++)
for(int j=1;j<=m;j++)
for(int l=1;l<j;l++)
f[i][j]=min(f[i][j],max(f[i-1][l],d[j]-d[l]));
pri(m,k);
}