对于第一问二分然后贪心判断即可

对于第二问,设f[i][j]为已经到j为止砍了i段,转移的话从$$ f[i][j]=\sigema f[k][j-1] (s[j]-s[k-1]<=ans)

这里用权和嘴和优化成nm的即可

#include<iostream>
#include<cstdio>
using namespace std;
const int N=50005,mod=10007;
int n,m,a[N],f[N],la[N];
long long sm[N],s[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
bool ok(int w)
{
int sum=0,s=1;
for(int i=1;i<=n;i++)
{
if(sum+a[i]>w)
sum=a[i],s++;
else
sum+=a[i];
}
return s<=m;
}
int main()
{
n=read(),m=read()+1;
int l=0,r=0,ans,ans2=0;
for(int i=1;i<=n;i++)
a[i]=read(),l=max(l,a[i]),r+=a[i],sm[i]=sm[i-1]+a[i];
while(l<=r)
{
int mid=(l+r)>>1;
if(ok(mid))
r=mid-1,ans=mid;
else
l=mid+1;
}
int las=0;
for(int i=1;i<=n;i++)
{
while(sm[i]-sm[las]>ans)
las++;
la[i]=las;
}
for(int i=0;i<=n;i++)
s[i]=1;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
f[j]=(s[j-1]-s[la[j]-1])%mod;
s[0]=0;
for(int j=1;j<=n;j++)
s[j]=s[j-1]+f[j];
ans2=(ans2+f[n])%mod;
}
printf("%d %d\n",ans,ans2);
return 0;
}

最新文章

  1. 8.GitHub实战系列~8.使用GitHub建立自己的免费博客
  2. nodejs 使用Google浏览器进行可视化调试——Node Inspector工具
  3. C++虚函数浅探
  4. Linux下显示IP地理位置信息的小工具-nali
  5. 【cl】Json学习
  6. wav文件格式分析(一)
  7. U盘启动笔记本无法安装Win7问题和解决
  8. Nodejs学习笔记(七)--- Node.js + Express 构建网站简单示例
  9. 2015-2-10 Linux 知识
  10. SDK更新问题解决
  11. ISNULL
  12. OC - 30.如何封装自定义布局
  13. ReactiveSwift源码解析(一) Event与Observer代码实现
  14. UIViewController生命周期控制-开发规范
  15. 转 Caffe学习系列(3):视觉层(Vision Layers)及参数
  16. hibernate入门-基本配置及简单的crud操作
  17. 【原创】大叔经验分享(40)hdfs关闭kerberos
  18. 在mybatis中resultMap与resultType的区别
  19. location search的中文加密
  20. AtCoder square869120 Contest #3 F sushi

热门文章

  1. PCB中贴片元器件的引脚规范(allegro)
  2. 基本dos
  3. conflunce安装配置
  4. PyUV: Python高性能网络库
  5. MySQL prepare语句的SQL语法
  6. bzoj5105 晨跑 数论lcm
  7. poj - 2195 Going Home (费用流 || 最佳匹配)
  8. 将windows应用程序注册为windows服务
  9. P2910 [USACO08OPEN]寻宝之路Clear And Present Danger 洛谷
  10. BNU2017校赛