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

    第一问二分答案

    第二问dp需优化空间和时间

    坑了一天 才写出个坑爹坑爹程序

    program hehe;
    const
     q=10007;
    var
     ans,s,min,max,n,m,i,j,k,l,t:longint;
     sum,h:array[0..50000] of longint;
     d:array[0..50000,0..1] of integer;
    
      function ok(a:longint):boolean;
      var
       f,g,cnt:longint;
      begin
       cnt:=0;
       g:=0;
       for f:=1 to n do
       begin
        g:=g+h[f];
        if g>a then
        begin
         inc(cnt);
         g:=h[f];
        end;
        if cnt>m then exit(false);
       end;
       exit(true);
      end;
    
      function ef(l,r:longint):longint;
      var
       mid:longint;
      begin
       mid:=(l+r)>>1;
       if l=r then exit(l);
       if ok(mid) then exit(ef(l,mid))
       else exit(ef(mid+1,r));
      end;
    
      function mini(a,b:longint):longint;
      begin
       if a>b then exit(b);
       exit(a);
      end;
    
    begin 
     readln(n,m);
     for i:=1 to n do
     begin
      read(h[i]);
      sum[i]:=h[i]+sum[i-1];
      if h[i]>max then max:=h[i];
      s:=s+h[i];
     end;
     min:=ef(max,s);
     write(min,' ');
     t:=0;
     s:=0;
     for i:=1 to n do
     if sum[i]<=min then
     d[i,0]:=1
     else break;
     for l:=1 to m do
     begin
      j:=l and 1;
      s:=0;
      t:=j xor 1;
      for i:=1 to n do
      begin
       s:=s+d[i-1,j xor 1];
       k:=t;
       while (k<i-1)and(sum[i]-sum[k]>min) do
       begin
        s:=s-d[k,j xor 1];
        inc(t);
        inc(k)
       end;
       d[i,j]:=s mod q;
      end;
      ans:=(ans+d[n,j])mod q;
     end;
     writeln(ans);
    end.

    1044: [HAOI2008]木棍分割

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2111  Solved: 764
    [Submit][Status][Discuss]

    Description

    有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长度最大的一段长度最小. 并将结果mod 10007。。。

    Input

    输入文件第一行有2个数n,m. 接下来n行每行一个正整数Li,表示第i根木棍的长度.

    Output

    输出有2个数, 第一个数是总长度最大的一段的长度最小值, 第二个数是有多少种砍的方法使得满足条件.

    Sample Input

    3 2
    1
    1
    10

    Sample Output

    10 2

    HINT

    两种砍的方法: (1)(1)(10)和(1 1)(10)

    数据范围  

       n<=50000, 0<=m<=min(n-1,1000).

       1<=Li<=1000.

    Source

     
    [Submit][Status][Discuss]


    HOME Back

  • 相关阅读:
    Linux系统自带服务罗列
    几个有用的shell命令
    Zabbix
    RaspberryPi3安装CentOS7教程
    grafana简介
    负载均衡之Haproxy配置详解(及httpd配置)
    CentOS7版本的新特性
    文件系统目录结构
    openstack部署dashboard
    openstack核心组件--cinder存储服务(6)
  • 原文地址:https://www.cnblogs.com/chensiang/p/4553120.html
Copyright © 2011-2022 走看看