Aizu 1333 Beautiful Spacing

来源:互联网 发布:网络下单系统 编辑:程序博客网 时间:2024/05/16 00:53

这题为某种取最值的dp提供一种解题思路,通过二分,可以使得时间复杂度从n^2降到nlogn。

dp我是倒序做的,定义dp[i]表示从第i个为该行第一个单词时,最大的空格是否小于二分的答案。

再定义两个指针从后往前边做边扫,再弄个前缀和判断指针之间是否有解,再来决定这个第i位的dp值的真假。

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#include<cstring>using namespace std;const int maxn=5*1e4+7;int dp[maxn];int c;int n;int a[maxn];int sum[maxn];int cal(int i,int j){    return (c-(sum[j]-sum[i-1])+j-i-1)/(j-i);}bool check(int x){    int a,b,g;    a=b=n;    dp[n+1]=1;    g=0;    for(int i=n;i>=1;i--)    {        while(a>i&&((c-(sum[a]-sum[i-1]))/(a-i)<=0))        {            g-=dp[a+1];            a--;        }        for(;b>a;b--)g+=dp[b+1];        while(b>i&&(b==n||cal(i,b)<=x))        {            g+=dp[b+1];            b--;        }        if(g||a==n)dp[i]=1;        else dp[i]=0;    }    return dp[1];}int main(){    while(1)    {        scanf("%d %d",&c,&n);        if(n==0&&c==0)break;        for(int i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i];        int l=1,r=c-2,mid;        while(l<r)        {            mid=(l+r)/2;            if(check(mid))r=mid;            else l=mid+1;        }        printf("%d\n",l);    }    return 0;}


0 0