Given n wooden bars connected together, they are divided into m + 1 segments to minimize the maximum value of each segment, and the minimum value and the maximum value are the minimum number of partitions.
First, the water burst ...... Second-level answer: seconds later
The second question is somewhat difficult. First, let f [I] [J] indicate that the first J is used.♂Number of sub-solutions for segment I
Well, I didn't have any strange symbols.
So we have dynamic equations.
F [I] [J] = Σ f [I-1] [k] (sum [J]-sum [k] <= ans, k <j)
The worst case is O (M * n ^ 2 ).
We found that the lower bound of K increases monotonically, So we directly set K to the lower bound of K at the current J hour, and open a variable record K ~ Sum of fvalues of J
When J ++ is used, K is adjusted backward. In addition, the F array must be opened to scroll the array. Otherwise, the MLE
After writing, I handed in various slow gods ...... What do other people write?
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 50500#define Mo 10007using namespace std;int n,m,limit,ans;int maxlen=0,a[M],sum[M];int f[2][M];inline bool Judge(int x){int i,re=0,now=x;for(i=1;i<=n;i++){if(now+a[i]>x)++re,now=a[i];elsenow+=a[i];if(re>m)return false;}return true;}inline int Bisection(){int l=maxlen,r=sum[n];while(l+1<r){int mid=l+r>>1;if( Judge(mid) )r=mid;elsel=mid;}if( Judge(l) )return l;return r;}int main(){int i,j,k;cin>>n>>m;++m;for(i=1;i<=n;i++)scanf("%d",&a[i]),sum[i]=sum[i-1]+a[i],maxlen=max(maxlen,a[i]);limit=Bisection();f[0][0]=1;for(i=1;i<=m;i++){int temp=0;k=i-2;for(j=i;j<=n;j++){temp+=f[~i&1][j-1],temp%=Mo;while(sum[j]-sum[k+1]>limit)temp+=Mo-f[~i&1][++k],temp%=Mo;f[i&1][j]=temp;}ans+=f[i&1][n],ans%=Mo;}cout<<limit<<' '<<ans<<endl;}
Bzoj 1044 haoi2008 dual answer + Dynamic Planning