dp:http://blog.csdn.net/qq_36820605/article/details/72910904
二分:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
int m,k;
int a[509],s[509];
int le[509],rig[509];
int check(int x)
{
int t=1,p=0;
for(int i=m;i>=1;i--)
{
if(p+a[i]<=x) p+=a[i];
else t++,p=a[i];
}
return t;
}
int main()
{
scanf("%d%d",&m,&k);
for(int i=1;i<=m;i++)
scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
int l=0,r;
for(int i=1;i<=m;i++) l=max(l,a[i]);//有原则地缩小区间
r=s[m];
/*while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid)>k)
l=mid+1;
else r=mid-1;
}
int ans=l;*///正确的二分
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid)>k)
l=mid+1;
else r=mid;
}
int ans=l;//正确的二分
int ll=m;
for(int i=k;i>=1;i--)
{
int u=0,rr=ll;
while(u+a[ll]<=ans&&ll>=1)
{
u+=a[ll];
ll--;
}
le[i]=ll+1;
rig[i]=rr;
}
for(int i=1;i<=k;i++)
{
printf("%d %d
",le[i],rig[i]);
}
//printf("%d
",ans);
//printf("%d
",check(16));
return 0;
}
/*7 5
100 100 100 100 100 100 400*/