题意
有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长度最小, 并且输出有多少种砍的方法使得总长度最大的一段长度最小. 并将结果mod 10007
分析
设f[i][j]表示到第i个点,截取j个木棍且满足要求的方案数.
前缀和sum优化,那么i->j的长度就是sum[j]-sum[i-1]
f[i][j]中的j只和j-1有关,所以可以用滚存
每次k都要循环一遍,若sum[i]-sum[k]<=ans,
那么sum[i-1]-sum[k]<=ans(其中i-1>k)(因为sum数组是前缀和,满足单调递增)
因此我们可以用类似于单调队列的方法,开一个后缀数组g.
如果sum[i]-sum[k]<=ans,就把计算后的值赋到g[i]中去.
在以后每个小于i的数中,若i>k,i就可以加上g数组
http://blog.csdn.net/orpinex/article/details/7088191
代码
1 | #include <cstdio> |