zoukankan      html  css  js  c++  java
  • bzoj 1044: [HAOI2008]木棍分割

    2016-06-20

    第一问是个二分的经典入门题

    第二问很容易发现一个DP f[i][j]前i个木棍分j次合法方案数,f[i][j]=f[k][j-1]+...+f[i-1][j-1]; 但这样时间复杂度是O(mn^2),空间复杂度是O(mn) 但我们发现对于相同的j随着i的增加,对应的k也增加,那我们可以根据这个单调性,用前缀和来做到转移复杂度为O(1),空间可以用滚动数组来解决,本来我偷懒用short int开数组,不用滚动数组。结果T了一半,早就听说数组大了会使程序变慢,今天我可算知道了,泪。。。。。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<queue>
     7 #define M 100008
     8 #define ll long long
     9 #define Mo 10007
    10 using namespace std;
    11 ll read()
    12 {
    13     char ch=getchar();
    14     ll x=0,f=1;
    15     for(;ch<'0'||ch>'9';ch=getchar())
    16       if(ch=='-')
    17         f=-1;
    18     for(;ch>='0'&&ch<='9';ch=getchar())
    19       x=x*10+ch-'0';
    20     return x*f;
    21 }
    22 short int f[50010][2];
    23 int n,m,a[50009],l,r,ans,b[50009],p=1,q;
    24 bool pan(int x)
    25 {
    26     int q=0,sum=0;
    27     for(int i=1;i<=n;i++)
    28       {
    29           q+=a[i];
    30           if(q>x)
    31             {
    32                 sum++;
    33                 q=a[i];
    34           }
    35       }
    36     if(sum<=m)
    37       return 1;
    38     return 0;
    39 }
    40 int main()
    41 {
    42     n=read();
    43     m=read();
    44     for(int i=1;i<=n;i++)
    45       {
    46         a[i]=read();
    47         l=max(a[i],l);
    48         r+=a[i];
    49       }
    50     for(;l<=r;)
    51       {
    52           int mid=(l+r)>>1;
    53           if(pan(mid))
    54             {
    55                 ans=mid;
    56                 r=mid-1;
    57             }
    58         else
    59           l=mid+1;
    60       }
    61     printf("%d ",ans);
    62     for(int i=1;i<=n;i++)
    63       a[i]+=a[i-1];
    64     for(int i=1;i<=n;i++)
    65       if(a[i]<=ans)
    66         f[i][p]=1;
    67     int an=f[n][p];
    68     for(int i=1;i<=n;i++)
    69       b[i]=f[i][p]+b[i-1];
    70     for(int i=1;i<=m;i++)
    71       {
    72           int h=0;
    73           for(int j=i+1;j<=n;j++)
    74             {
    75              for(;a[j]-a[h]>ans;h++);
    76              if(h)
    77                     f[j][q]=(b[j-1]-b[h-1]+Mo)%Mo;
    78              else
    79                     f[j][q]=b[j-1]%Mo;
    80           }
    81         for(int j=1;j<=n;j++)
    82            b[j]=f[j][q]+b[j-1];
    83         swap(p,q);
    84         an=(an+f[n][p])%Mo;
    85       }
    86     printf("%d
    ",an);
    87     return
  • 相关阅读:
    vim 真是上瘾啊
    乐此不疲
    .vimrc .bashrc
    github
    隐藏c语言烦人的{ }
    linux mint console-setup
    samsung n143 brightness on linux mint
    荒漠甘泉——1月31日
    嵌入式 方向?
    python2与python3的区别
  • 原文地址:https://www.cnblogs.com/xiw5/p/5601711.html
Copyright © 2011-2022 走看看