博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【DP】书的复制
阅读量:4607 次
发布时间:2019-06-09

本文共 1288 字,大约阅读时间需要 4 分钟。

【思路】

(区间)DP

F[I][J]表示前i本书分给j个人用的最短时间
由于每一次j的状态由比j小的状态得出,所以要先枚举j,然后枚举i,接着枚举上一次抄书的人是谁

我觉得,难点在于输出

具体见代码

压行压到手抽筋

#include
#include
#include
using namespace std;inline int read(){ char chr=getchar();int f=1,ans=0; while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();} while(isdigit(chr)) {ans=ans*10;ans+=chr-'0';chr=getchar();} return ans*f;}int a[505],f[505][505],n=read(),m=read(),s=0,&ans=f[n][m],num=0,w=n,pre[505],x;void output(int x){ if(x>0) output(pre[x]-1); else return; if(pre[x]<=0) return;printf("%d %d\n",pre[x],x);}//这里递归输出int main(){ memset(f,127/2,sizeof(f));memset(pre,0,sizeof(pre));f[0][1]=0; if(!n&&!m) return 0;//坑点!!! for(int i=1;i<=n;i++) a[i]=read(),f[i][1]=f[i-1][1]+a[i];//前i本书都交给第一个人抄(即a[i]的前缀和) for(int j=2;j<=m;j++) for(int i=j;i<=n;i++) for(int k=j;k<=i;k++){ int x=max(f[k-1][j-1],f[i][1]-f[k-1][1]);//取两者最长的抄书时间 if(f[i][j]>x) f[i][j]=x;//取最小值 } for(int i=n;i>=1;i--){//这里贪心,因为后面的人抄尽量多,前面少,所以倒过来枚举 s+=a[i]; if(s>ans) s=a[i],pre[w]=i+1,w=i;//pre[w]记录这个人抄书的开始位置 } printf("%d %d\n",1,w);//第一组特判 output(n);//递归输出 return 0;}

打完收工

hia~hia~hia~

转载于:https://www.cnblogs.com/zhenglw/p/9507881.html

你可能感兴趣的文章
bzoj 4595 激光发生器
查看>>
multi cookie & read bug
查看>>
js时间转换
查看>>
(转载) Android Studio你不知道的调试技巧
查看>>
队列实现霍夫曼树
查看>>
【Java】图片高质量缩放类
查看>>
详解定位与定位应用
查看>>
【前端开发】 5分钟创建 Mock Server
查看>>
pyspider 示例
查看>>
JAVA 笔记(一)
查看>>
c# 范型Dictionary实用例子
查看>>
C#实现动态页面静态化
查看>>
IIS处理并发请求时出现的问题
查看>>
优先队列小结
查看>>
线程安全与可重入函数之间的区别与联系
查看>>
{Nodejs} request URL 中文乱码
查看>>
异常及日志使用与项目打包
查看>>
努力,时间,坚持,自律
查看>>
Hadoop2.6.0 动态增加节点
查看>>
图论的一些概念、定理
查看>>