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

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

dp例题 or 水题

先说下题意吧,题面给的题意我都看不懂:

\(n\)本书,每本书有一个页数%a_i%。每个人能写连续的几本书,他们写书的速度可以认为是1页1天。求让\(k\)个人抄完这\(n\)本书的最短时间。

PS:\(k\)个人抄书的时间是其中抄的最慢的人用的时间。

dp的状态非常容易想:dp[i][j]表示前\(i\)本书,用\(j\)个人抄的最短时间。

那么显然可以枚举一个小于\(i\)\(j\)来更新状态,这个方程式很水就不讲了。

重点在于输出方案。

得到的最短时间,根据题意,我们要让后面的人尽可能的抄更多的书。

做法很简单,从后面开始递归,枚举出最大的一段满足的区间供给那个人抄,然后剩下的区间就给剩下的人抄。

代码:

#include
#include
#include
const int maxn = 505;int dp[maxn][maxn];int a[maxn], b[maxn];int n, m;void print(int maxv, int pos){ if(pos == 0) return; int sum = 0; int i; for(i = pos; i >= 1; i--) { sum += a[i]; if(sum > maxv) break; } i++; print(maxv, i - 1); printf("%d %d\n", i, pos);}int main(){ memset(dp, 0x3f, sizeof dp); scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); b[i] = b[i - 1] + a[i]; } for(int i = 1; i <= n; i++) dp[i][1] = b[i]; /* for(int k = 2; k <= m; k++) { for(int i = 2; i <= n; i++) { for(int j = 1; j < i; j++) { dp[i][k] = std::min(dp[i][k], std::max(dp[j][k - 1], a[i] - a[j])); } } } */ for(int i = 2; i <= n; i++) { for(int j = 1; j < i; j++) { for(int k = 2; k <= m; k++) { dp[i][k] = std::min(dp[i][k], std::max(dp[j][k - 1], b[i] - b[j])); } } } //printf("%d\n", dp[n][m]); print(dp[n][m], n); return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9905806.html

你可能感兴趣的文章
正则表达式匹配数字
查看>>
前端模块化
查看>>
QIBO CMS SQL Injection Via Variable Uninitialization In \member\special.php
查看>>
二维数组---模拟斗地主
查看>>
【转】(DT系列六)devicetree中数据和 struct device有什么关系
查看>>
【前端性能】必须要掌握的原生JS实现JQuery
查看>>
mysql系统变量
查看>>
svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
查看>>
JavaScript 编码规范(中文/Airbnb公司版)
查看>>
DNX/ASP.NET 5的xUnit入门向导
查看>>
正则表达式—匹配连续重复的字符
查看>>
如何在一个月内改善你的生活
查看>>
beyond compare比较工具设置
查看>>
Java中的事务
查看>>
Spring Ajax一个简单样例
查看>>
传递给数据库 'master' 中的日志扫描操作的日志扫描号无效
查看>>
导入https证书
查看>>
SAP R3和JAVA交换数据之JCO
查看>>
近期给朋友推荐的笔记本型号
查看>>
sqlserver使用存储过程发送http请求
查看>>