# BZOJ 1044 [HAOI2008]木棍分割

f[i][j]=sigma f[k][j-1](sum[i]-sum[k]<=ans)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100009;
const int mm=10007;

int n,m;
int s[maxn]={0};

int tot=0;
int l=0,r=0,mid=0,ans=0;

int f[maxn]={0};
int g[maxn]={0};

int Isok(){
int last=0,cnt=0;
for(int i=1;i<=n;++i){
if(s[i]-s[last]>mid){
++cnt;last=i-1;
}
}
++cnt;
if(cnt>m)return 0;
else return 1;
}

int main(){
scanf("%d%d",&n,&m);++m;
for(int i=1;i<=n;++i){
scanf("%d",&s[i]);
l=max(l,s[i]);
s[i]+=s[i-1];
}

r=1000000000;
while(l<=r){
mid=(l+r)>>1;
if(Isok()){
ans=mid;
r=mid-1;
}else{
l=mid+1;
}
}
printf("%d ",ans);

for(int i=1;i<=n;++i){
if(s[i]<=ans)g[i]=1;
else g[i]=0;
}
for(int j=2;j<=m;++j){
for(int i=1;i<=j-1;++i)f[j]=0;
int tm=g[j-1],last=j-1;
for(int i=j;i<=n;++i){
while((s[i]-s[last]>ans)){
tm=(tm-g[last]+mm)%mm;++last;
}
f[i]=tm;
tm=(tm+g[i])%mm;
}
tot=(tot+f[n])%mm;
//		for(int i=1;i<=n;++i)cout<<f[i]<<' ';
//		cout<<endl;
for(int i=1;i<=n;++i)g[i]=f[i];
}

printf("%d\n",tot);
return 0;
}


posted @ 2018-03-04 08:56  ws_zzy  阅读(104)  评论(0编辑  收藏