[bzoj1044][HAOI2008]木棍分割

#include<iostream>
#include<cstdio>
#define mod 10007
using namespace std;
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

int f[2][50005];
int s[50005];
int n,m,ans1;

bool check(int x)
{
// cout<<"check"<<x<<endl;
int num=0,nown=0;
for(int i=1;i<=n;i++)
{
if(s[i]>x)return false;
nown+=s[i];if(nown>x){nown=s[i];num++;}
}
if(nown>0)num++;
return num<=m;
}

int main()
{
int l=1,r=1e9,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid))ans1=mid,r=mid-1;
else l=mid+1;
}
f[0][0]=f[1][0]=1;
for(int i=1;i<=n;i++)s[i]+=s[i-1];
int pre=0,nown=1;
for(int j=1;j<=m;j++,pre=nown,nown^=1)
for(int i=1,tot=0,l=1,r=0;i<=n;i++)
{
tot=(tot+f[pre][r++])%mod;
while(l<=r&&s[r]-s[l-1]>ans1)tot=(tot+mod-f[pre][l-1])%mod,++l;
f[nown][i]=tot;
// cout<<i<<" "<<l<<" "<<r<<" "<<tot<<endl;
}
printf("%d %d\n",ans1,f[pre][n]);
return 0;
}

posted @ 2017-03-03 22:26  FallDream  阅读(222)  评论(0编辑  收藏