zoukankan      html  css  js  c++  java
  • [bzoj1044]木棍分割

    第一个问题可以用贪心+二分解决
    第二个问题用f[i][j]表示i次分割后分割到j且满足条件的方案数,$f[i][j]=sum_{k<j且sum[j]-sum[k]<=ans}f[i-1][k]$
    优化时间:前缀和优化,二分要先预处理出来(也可以用优先队列)
    优化空间:发现f并没有什么用处,只需要记录前缀和数组,再对其滚动即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define mod 10007
     4 int n,m,ans,a[50005],b[50005],sum[2][50005];
     5 bool pd(int k){
     6     int s=0,ans=0;
     7     for(int i=1;i<=n;i++){
     8         s+=a[i];
     9         if (s>k){
    10             ans++;
    11             s=a[i];
    12         }
    13     }
    14     return ans<=m;
    15 }
    16 int main(){
    17     scanf("%d%d",&n,&m);
    18     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    19     int l=0,r=1000*n;
    20     for(int i=1;i<=n;i++)l=max(l,a[i]);
    21     while (l<r){
    22         int mid=(l+r>>1);
    23         if (pd(mid))r=mid;
    24         else l=mid+1;
    25     }
    26     for(int i=2;i<=n;i++)a[i]+=a[i-1];
    27     for(int i=1;i<=n;i++)sum[0][i]=(sum[0][i-1]+(a[i]<=l))%mod;
    28     for(int i=1;i<=n;i++)b[i]=lower_bound(a+1,a+n+1,a[i]-l)-a-1;
    29     ans=(a[n]<=l);
    30     for(int i=1;i<=m;i++){
    31         int p=(i&1);
    32         for(int j=i+1;j<=n;j++){
    33             r=(sum[p^1][j-1]-sum[p^1][b[j]]+mod)%mod;
    34             sum[p][j]=(sum[p][j-1]+r)%mod;
    35             if (j==n)ans=(ans+r)%mod;
    36         }
    37     }
    38     printf("%d %d",l,ans);
    39 }
    View Code
  • 相关阅读:
    组件映射
    联合主键关联
    一对一单向双向主键关联
    7函数
    forEach与map
    3运算符与表达式
    作用域声明提升
    php程序设计 1,2章节
    angularJs(3)过滤器
    angularJs(1)指令篇
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11756699.html
Copyright © 2011-2022 走看看