很久之前打的题,现在补篇博客

打滚动数组

#E. 木棍分割

Accepted

100

1712 ms

1512 KiB

 

2019-05-07 17:01:23

Short 不打滚动数组

#419. [HAOI2008]木棍分割

Accepted

100

5219 ms

100960 KiB

2019-05-07 15:12:41

木棍分割 题解

木棍分割

内存限制:128 MiB时间限制:3000 ms标准输入输出

题目类型:传统评测方式:文本比较

提交提交记录返回比赛

题目描述

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

并将结果mod 10007。。。

输入格式

输入文件第一行有2个数n,m.接下来n行每行一个正整数Li,表示第i根木棍的长度.n<=50000,0<=m<=min(n-1,1000),1<=Li<=1000.

输出格式

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

样例

样例输入

3 2

1

1

10

样例输出

10 2

数据范围与提示

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

二分答案+dp滚动数组

第一步 二分答案求长度

每次枚举木棍可以分成的值下界为所有木棍最小值上界为所有木棍最大值

当 当前值可以分成的时候,比它小的值可能可以分成故让当前r=mid-1

当 当前值不可以分成的时候比它大的值可能分成故让l=mid+1

当r>mid时得到最终答案

然后find函数检验当前值是否可以分成

具体操作:枚举!

初始化add=0,指针=0,块数=0;

只需要扫一遍当add<=x的时候直接在add加上当前这个值;否则令分成的块数++ 并且令add值重新附成当前指针指向的木棍长度

值得注意的一点是 当指针已经指向最后一个数的时候 若add不为0 块数需要+1

最后比较块数与m即可

第二步 dp求方案数

首先暴力枚举求方案数肯定会超时,很自然的想到统计方案需要用dp

首先想要至少开二维 当前切割位置可能由任何满足之间木棍长度之和<=第一步求得的答案   的切割位置转移过来

需要枚举每一根木棍(枚举当前切割的位置) ,每一个前一个切割的位置,和切割的次数

可以看到是n2*m复杂度 还不如打一个暴力 同样是t掉

dp暴力转移式$f[i][j]+=f[k][j-1](if(sum[i]-sum[k-1]<=maxn)$

善良的出题人肯定不会让你AC的

你会得到0分的好成绩

Time Limit Exceeded

0

30150 ms

然后我们要考虑一些优化

我们可以看到事实上一些位置是加重了的

在每一个切割次数下要枚举一遍k 每次都枚举了k 但事实上每个木棍长是始终不变的

每次枚举一遍就太区区了

我们需要一个数据结构来快速查询每一段所代表的值并且维护一个before数组代表在其之前最长的一段<=第一步求的答案

before可以暴力去求也可以用 lower_bound

for(ll i=1;i<=n;i++)

last[i]=lower_bound(sum+1,sum+i+1,sum[i]-cun)-sum;

理解一下

例如 9 3

5 4 3 2 1 2 3 4 5

这一组数据对应 before为

1 1 1 1 2 2 3 5 7

cun=7;

sum 值 5 9 12 14 15 17 20 24 29

对应下标 1 2  3  4  5   6   7  8  9

last[1]=1 sum[1]-cun=-4

last[2]=1 sum[2]-cun=0

last[3]=1 sum[3]-cun=3

last[4]=1 sum[4]-cun=5

last[5]=2 sum[5]-cun=6

last[6]=2 sum[6]-cun=8

last[7]=3 sum[7]-cun=11

last[8]=5 sum[8]-cun=15

last[9]=7 sum[9]-cun=20

lower_查到的下标 事实就是sum[i]-sum[now]<=cun 其实还是挺好理解的

然后就是数据结构

事实上 考虑到区间查值 我们可以用前缀和(当然树状数组不行 并没有单点修改仅仅是每次要查值而已 前缀和维护是o(1)  树状数组o(logn))

然后dp就完了

代码

#include<bits/stdc++.h>
#define re register
#define i_ inline
#define huan cout<<endl
#define ll int
#define A 50010
ll n,m,before[A],a[A],maxx=-1,last[A],sum[A],su[A],jilu;short f[50101][2];
using namespace std;
#define mod 10007
inline ll read()
{
ll f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
i_ bool find(ll x)
{
ll zhizhen=0,zan=0,add=0,dangqian;
if(x<maxx)
return false;
while(zhizhen<=n)
{
zhizhen++;
if(add+a[zhizhen]<=x)
{
add+=a[zhizhen];
}
else
{
zan++;
add=a[zhizhen];
dangqian=zhizhen;
}
}
if(add!=0)
zan++;
return (zan<=m?1:0);
}
i_ ll er()
{
ll l=0,r=sum[n],mid,ans;
while(l<=r)
{
mid=(l+r)>>1;
if(find(mid)==1)
ans=mid,r=mid-1;
else
l=mid+1;
}
// printf("m=%lld\n",jilu);
return ans;
}
void tiaos(bool x)
{
printf("记录=%lld\n",jilu);
if(x)
{
for(ll i=1;i<=n;i++)
printf("last[%lld]=%lld ",i,last[i]);
cout<<endl;
for(ll i=1;i<=n;i++,puts(""))
for(ll j=0;j<=m;j++)
printf("f[%lld][%lld]=%lld ",i,j,f[i][j]);
return ;
}
else
{
for(ll i=1;i<=n;i++,puts(""))
for(ll j=0;j<=m;j++)
printf("f[%lld][%lld]=%lld ",i,j,f[i][j]);
}
}
int main()
{
// freopen("out.in","r",stdin);
// freopen("wrong.out","w",stdout);
n=read(),m=read();
m+=1;
for(ll i=1;i<=n;i++)
{
a[i]=read();
sum[i]=sum[i-1]+a[i];
maxx=max(a[i],maxx);
} ll cun=er(),zhe=1; m=m-1; ll uscao=0;
for(ll i=1;i<=n;i++)
{
if(sum[i]>cun) break;
else f[i][0]=1;
}
for(ll i=1;i<=n;i++)
last[i]=lower_bound(sum+1,sum+i+1,sum[i]-cun)-sum;
for(ll j=1;j<=m;j++)
{
for(ll i=1;i<=n;i++)
su[i]=su[i-1]+f[i][j&1^1],f[i][j&1]=0;
for(ll i=j+1;i<=n;i++)
f[i][j&1]=(f[i][j&1]+su[i-1]-su[last[i]-1])%mod;
uscao=(uscao+f[n][j&1])%mod;
} // tiaos(1);
cout<<cun<<" "<<uscao;
}

最新文章

  1. 企业应用开发模式 ERP项目中应用到的技术和工具
  2. cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
  3. HTML表单入门基础
  4. Android应用签名
  5. .NET 使用CouchBase 基础篇
  6. 离线安装chrome插件
  7. Fortran编译多个文件(转载)
  8. Why java main function is declared as static type?
  9. statspack系列2
  10. 利用微信公众平台实现自动回复消息—java版
  11. bzoj3112 [Zjoi2013]防守战线
  12. Django rest framework源码分析(2)----权限
  13. mapper.xml 的配置
  14. qt程序编译错误:could not exec ‘/usr/lib/x86_64-linux-gnu/qt4/bin/qmake’
  15. Linux基础命令---mktemp
  16. Java Selenium 笔记
  17. php empty详解
  18. Dialog插件artDialog
  19. Swift - 把汉字转换为拼音,并且截取首字母做索引用
  20. Asset Catalog Help (四)---Adding an iOS App Icon Set or Launch Image Set

热门文章

  1. 第二章 FreeBSD之开机关机命令
  2. [题解] CF786B Legacy
  3. 一个入门级CTF的Reverse
  4. Docker 部署阿里云RocketMQ 4.5.1
  5. 定义私有属性: *String name; * int age; * String gender; * int salary; Date hiredate;//入职时间
  6. jQuery清空元素和克隆元素
  7. golang:面向对象总结
  8. 佳能m62套机5500 佳能EOS M50 M6 MARK2 II二代 最低到过5800
  9. Ansible_编写Playbook文件
  10. 戴尔 R730xd 服务器更改管理口密码 图文教程