P1264 复制书稿
2017年8月4日
DP+贪心
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int M, K;//M本书,K个人;
int Pages[600];
int F[600][600];//DP;
int T[600][600];//第i本到第k本的页数;
struct Assign{
int st, ed, L;
}S[600]; int ans = 0;
bool cmp(Assign a, Assign b)
{
return ((a.st < b.st) || (a.st == b.st && a.L < b.L));
}
void DP()
{
memset(F, 10, sizeof(F));
for(int i = 0; i <= M; i++) F[1][i] = T[1][i];
for(int i = 1; i <= K; i++) F[i][0] = 0;
for(int i = 2; i <= K; i++)
for(int k = 1; k <= M; k++)
for(int j = 1; j < k; j++){
F[i][k] = min(F[i][k], max(F[i - 1][j], T[j + 1][k]));
}
}
void Datas()
{
T[1][1] = Pages[1];
for(int i = 2; i <= M; i++) T[1][i] = T[1][i - 1] + Pages[i];
for(int i = 2; i <= M; i++)
for(int k = i; k <= M; k++)
T[i][k] = T[1][k] - T[1][i - 1];
}
void Search()
{
static int mid = F[K][M];
int head = M, tails = M;//从后到前贪心搜索;
for(; ; )
{
while(T[tails - 1][head] <= mid && tails - 1 >= 1) tails--;
S[++ans].st = tails; S[ans].ed = head;
S[ans].L = T[tails][head];
if(tails == 1) break;
else head = --tails;
}
sort(S + 1, S + 1 + ans, cmp);
}
int main()
{
//Putin
cin >> M >> K;
for(int i = 1; i <= M; i++) cin >> Pages[i];
//
Datas();
DP();
Search();
//Printout
for(int i = 1; i <= ans; i++)
cout << S[i].st << ' ' << S[i].ed << endl;
//
return 0;
}