#include<cstdio>
#include<cstring>
int f[510][510];// f[i][j] 表示把 前 i本书 分给 k 个人
int ma[510],su[510];
int n,m;
int maxx(int x,int y) { return x>y?x:y; }
int minn(int x,int y) { return x<y?x:y; }
void ff()
{
for(int j=2;j<=m;j++)
{
for(int i=j;i<=n;i++)
{
for(int k=j;k<=i;k++)//k 为 最后一个人拿到的第一本书的编号
{
int an=0;
an=maxx(f[k-1][j-1],su[i]-su[k-1]);
f[i][j]=minn(f[i][j],an);
}
}
}
}
void pr(int l,int r) //打印当前左右边界内的部分
{
int ss=0;
for(int i=r;i>=l;i--)
{
if(ss+ma[i]>f[n][m])
{
pr(l,i);
printf("%d %d\n",i+1,r);//逆序输出,回溯时才打印
return ;
}
ss+=ma[i];
}
printf("%d %d\n",1,r);//关于第一个人的特殊处理(边界)
}
int main()
{
memset(su,0,sizeof(su));//预处理前 N 项和的数组
memset(f,63,sizeof(f));
scanf("%d %d",&n,&m); if(n==0) return 0;
for(int i=1;i<=n;i++)
{
scanf("%d",&ma[i]);
su[i]=ma[i]+su[i-1];
f[i][1]=su[i];
}
ff();
//printf("%d\n",f[n][m]);
pr(1,n);
return 0;
}
LuoguP1281书的复制
最新推荐文章于 2021-04-11 08:56:13 发布