机器分配----线性dp难题(对于我来说)
题目:
总公司拥有高效设备M台, 准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M <= 15,N <= 10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。
(非常简洁的题面,没有之一)
输入:
第1行有两个数,第一个数是分公司数N,第二个数是设备台数M。接下来是一个N*M的矩阵,表明了第i个公司分配j台机器的盈利。
输出:
第1行输出最大盈利值。接下来N行,每行2个数,即分公司编号和该分公司获得设备台数。
样例:
3 3 70
30 40 50 ===> 1 1
20 30 50 2 1
20 25 30 3 1
题面也很好理解:找出最大的分配方式,并输出路径。
思路:
1.求最大值,思路是线性dp,第 i 行 j 列的结果只与这一行选几个,和他上面的行选几个有关,所以可以用dp的思路来解。转移方程是
dp[ i ][ j ]=max(dp [ i ][ j ],dp[ i - 1 ][ k ]+a[ i ][ j - k ] );
2.保存路径
这一步是比较难的,对代码能力的要求较高,也是这道题的考点,先上一个比较暴力的,但肯定对的:
void Print(int i,int j){
if(i==0)return;
for(int k=0;k<=j;k++){
if(Max==dp[i-1][k]+a[i][j-k]){
Max=dp[i-1][k];
Print(i-1,k);
printf("%d %d\n",i,j-k);
break;
}
}
}
递归输出,在主函数里Print(n,m)。这样写相当于每一行都重新算了一遍。
(ps:这道题题目要求本来是输出N行,每行包括第 i 家公司和他所选的台数,但是这样递归输出,如果有的公司一台没选,这样的公司是不会输出的)
错误样例:2 2 666
1 666======》 1 2
1 1
(但是这道题的数据太菜了,这样写也能a。。。)
第二种方法:一般的用res数组保存每排每列所选的k,然后输出(我改这个改了11次也没过,哭辽!)
(不要抄这个!不要抄这个!不要抄这个!这个会WA!!!)
就讲一下思路吧。。。
if(dp[i][j]<=dp[i-1][k]+a[i][j-k]){
dp[i][j]=dp[i-1][k]+a[i][j-k];
M[i][j]=k;
}
if(Max<=dp[i][j]){
Max=dp[i][j];
F1=i;F2=j;
}
M[ i ][ j ]保存dp[ i ][ j ]的决策中选的那个k,F i,F j保存最大结果的 i, j 。
因为要从1~N输出,所以需要递归保存一下:
void Print(int i,int j){
if(M[i][j]==0){
ans[i]=j-M[i][j];
return;
}
Print(i-1,M[i][j]);
ans[i]=j-M[i][j];
}
ans[ i ]保存第 i 个公司所选机器数量。
然后输出结果即可。
这道题为什么这样写会WA呢?
附上错误样例:
2 15
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
大家自己思考一下,这样该怎么输出路径?
显然 1 1 1 0
2 1 2 15
的结果都是一样的,MAX=2。
标准答案和这个代码的结果各据其一。
就是一个多解没spj压正解的题。。。
总结:这道题主要难点有两个,一是转移方程,二是输出路径。
然后就没了。。。
机器分配----线性dp难题(对于我来说)的更多相关文章
- 机器分配——线性dp输出路径
题目描述 总公司拥有高效设备M台, 准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M <= 15 ...
- P2066 机器分配 (DP+DP输出)
题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...
- luogu P2066 机器分配[背包dp+方案输出]
题目背景 无 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15 ...
- 线性DP之机器分配
题目大意 自己瞅 (懒得打了) 思路 前面是很简单的线性dp,后面是模拟递归输出方案, 模拟递归可以设ny为机器数机器数,nx表示第nx个公司,tot为总盈利,那么则有\(a[nx][i]+dp[nx ...
- Luogu P2066 机器分配(dp)
P2066 机器分配 题面 题目背景 无 题目描述 总公司拥有高效设备 \(M\) 台,准备分给下属的 \(N\) 个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这 \(M\ ...
- 【线型DP】洛谷P2066 机器分配
[线型DP]洛谷P2066 机器分配 标签(空格分隔): 线型DP [题目] 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配 ...
- POJ2779 线性DP 或 杨氏三角 和 钩子公式
POJ2779 线性DP 或 杨氏三角 和 钩子公式 本来就想回顾一下基础的线性DP谁知道今早碰到的都是这种大难题,QQQQ,不会 这个也没有去理解线性DP的解法,了解了杨氏三角和钩子公式,做出了PO ...
- Qt容器类的对象模型及应用(线性结构篇:对于QList来说,sharable默认是false的,但对于接下来讲的QVector来说,sharable默认是true)
用Qt做过项目开发的人,肯定使用过诸如QList.QVector.QLinkList这样的模板容器类,它们虽然名字长的不同,但使用方法都大致相同, 因为其使用方法都大体相同,很多人可能随便拿一个容器类 ...
- JDOJ 1958 机器分配
JDOJ 1958: 机器分配 Description 某总公司拥有高效生产设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为总公司提供一定的盈利.问:如何分配这M台设备才能使国家得到 ...
随机推荐
- Linux:crond(crontab)定时任务
一..定义 Crond 是linux系统中用来定期执行命令或指定程序任务的一种服务或者软件.一般在安装完系统时,crond会默认存在. crond默认每分钟会检查系统中是否有需要执行的定时任务.如果有 ...
- [LeetCode]Mysql系列5
题目1 1112. 每位学生的最高成绩 编写一个 SQL 查询,查询每位学生获得的最高成绩和它所对应的科目,若科目成绩并列,取 course_id 最小的一门.查询结果需按 student_id 增序 ...
- Hadoop入门学习整理(一)
今天是2020年4月8日,是一个平凡而又特殊的日子,武汉在经历了77天的封城之后,于今日0点正式解封.从1月14日放寒假离开武汉,到今天已近3个月,学校的花开了又谢了.随着疫情好转,春回大地,万物复苏 ...
- Java编程风格
来自<The Elements of Java Style>-<Java编程风格>一书,值得一读的书籍,会让你在细节上节省很多时间,合作之间更加愉快! 好处不多说了,但是有几个 ...
- 关于bat脚本中的命令状态码相关的%errorlevel%变量
bat脚本中常用%errorlevel%表达上一条命令的返回值,即命令执行状态码.也称命令退出码 一般上一条命令的执行结果返回的值只有两种,0和非0 (如常见的1,2,4,5,9009等等),0一般会 ...
- Xmind 2020 破解教程
前言: 今天用xmind试用版记了会笔记,发现哎哟还真好用,于是乎我脑子一热,点击激活,发现年费好尼玛贵,瞬间我就冷静下来了. 于是乎,脑海里立马浮现出两个字:破解!好了废话不多说,直接上傻瓜教程.( ...
- 从SpringBoot源码看资源映射原理
前言 很多的小伙伴刚刚接触SpringBoot的时候,可能会遇到加载不到静态资源的情况. 比如html没有样式,图片无法加载等等. 今天王子就与大家一起看看SpringBoot中关于资源映射部分的主要 ...
- pandas 使用技巧
多列展示 查看DataFrame时,列数较多会省略中间列的信息,可以设置最大展示列数,代码如下: 1 import pandas as pd 2 pd.set_option('display.max_ ...
- 极简 Node.js 入门 - 4.3 可读流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- USB虚拟串口 使用基于stm32的RT-Thread
参考我的RT Thread论坛文章 https://www.rt-thread.org/qa/thread-422644-1-1.html