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

题解:先二分求最大长度的最小值,贪心的切看能不能满足条件,然后dp【i】【j】表示切了i刀,切到j的满足条件的方案数,然后复杂度是O(n*n*m),我们可以发现,转移是从一段连续的区间转移的,所以我们每次求上一层dp的前缀和来加速,复杂度就成了O(n*m),然后开二维dp会爆空间,我们需要滚动数组压缩空间

/**************************************************************
Problem: 1044
User: walfy
Language: C++
Result: Accepted
Time:8564 ms
Memory:2264 kb
****************************************************************/ //#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 10007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; int ans,dp[][N];
int a[N],sum[N],n,m,last[N];
bool ok(int x)
{
int now=,te=;
for(int i=;i<=n;i++)
{
if(now+a[i]<=x)now+=a[i];
else
{
te++;
now=a[i];
if(now>x)return ;
}
}
if(te>m)return ;
return ;
}
void prepare()
{
int l=,r=sum[n]+;
while(l<r-)
{
int m=(l+r)>>;
if(ok(m))r=m;
else l=m;
}
ans=r;
for(int i=;i<=n;i++)a[i]+=a[i-];
}
void gao()
{
int now=,pre=,ans1=;
dp[now][]=;
for(int i=;i<=m+;i++)
{
swap(now,pre);
memset(dp[now],,sizeof dp[now]);
sum[]=dp[pre][];
for(int j=;j<=n;j++)sum[j]=(sum[j-]+dp[pre][j])%mod;
int k=;
dp[now][]=;
for(int j=i;j<=n;j++)
{
while(a[j]-a[k]>ans)k++;
dp[now][j]=(sum[j-]-(k?sum[k-]:))%mod;
dp[now][j]=(dp[now][j]+mod)%mod;
}
ans1=(ans1+dp[now][n])%mod;
}
printf("%d %d\n",ans,(ans1+mod)%mod);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i]=sum[i-]+a[i];
}
prepare();
gao();
return ;
}
/********************
3 2
10 1 1
********************/

bzoj1044: [HAOI2008]木棍分割 二分+dp的更多相关文章

  1. [BZOJ1044][HAOI2008]木棍分割 二分+贪心+dp+前缀和优化

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4112  Solved: 1577 [Submit][St ...

  2. 【bzoj1044】[HAOI2008]木棍分割 二分+dp

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

  3. Luogu P2511 [HAOI2008]木棍分割 二分+DP

    思路:二分+DP 提交:3次 错因:二分写萎了,$cnt$记录段数但没有初始化成$1$,$m$切的次数没有$+1$ 思路: 先二分答案,不提: 然后有个很$naive$的$DP$: 设$f[i][j] ...

  4. [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)

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

  5. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

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

  6. BZOJ1044 [HAOI2008]木棍分割 【二分+Dp】

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4281  Solved: 1644 [Submit][St ...

  7. BZOJ 1044: [HAOI2008]木棍分割(二分答案 + dp)

    第一问可以二分答案,然后贪心来判断. 第二问dp, dp[i][j] = sigma(dp[k][j - 1]) (1 <= k <i, sum[i] - sum[k] <= ans ...

  8. bzoj1044[HAOI2008]木棍分割 单调队列优化dp

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4314  Solved: 1664[Submit][Stat ...

  9. BZOJ1044: [HAOI2008]木棍分割

    1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1580  Solved: 567[Submit][Statu ...

随机推荐

  1. Python爬虫实例(五) requests+flask构建自己的电影库

    目标任务:使用requests抓取电影网站信息和下载链接保存到数据库中,然后使用flask做数据展示. 爬取的网站在这里 最终效果如下: 主页: 可以进行搜索:输入水形物语 点击标题进入详情页: 爬虫 ...

  2. Java spring mvc多数据源配置

    1.首先配置两个数据库<bean id="dataSourceA" class="org.apache.commons.dbcp.BasicDataSource&q ...

  3. Mongo副本集的配置以及php node.js连接使用副本集

    最近弄了下mongodb的副本集, 首先说下没有认证情况的副本集,相对比较简单,因为环境有限,我在同一台服务器上做了模拟. --rest参数是打开web监控页面,比如我们这里监听37017端口,则打开 ...

  4. tow sum

    今天面试好打脸!!! 解决方案方法一:暴力法暴力法很简单.遍历每个元素 xx,并查找是否存在一个值与 target−x 相等的目标元素. public int[] twoSum(int[] nums, ...

  5. 使用dockerfile 创建ubuntu ssh镜像

    ############################################################ # Dockerfile to build ubunto ssh contai ...

  6. 如何通过iframe调用其他页面的内容

    我们在建站的时候经常会在页面出现同样的内容,比如公司简介之类的,这些东西很长,会减低网页的原创程度,相似度太高,对SE不是很友好.这时我们可以考虑把这部分内容写成一个单独的简单页面,然后通过ifram ...

  7. 一个兼职DBA的数据库运维经验 小米科技 xx@xiaomi.com 2011

    一个兼职DBA的数据库运维经验 小米科技  xx@xiaomi.com 2011 内存扩容 16G->64G ,调大bp后,凌晨说监控物理内存有余量情况下,开吃swap,内存泄露措施1  定时 ...

  8. js-jquery-SweetAlert2【三】INPUT TYPES

    1.text swal({ title: 'Input something', input: 'text', showCancelButton: true, inputValidator: funct ...

  9. Python:笔记(7)——yield关键字

    Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...

  10. ruby中的预定义变量(Predifined Variables)