【线型DP】洛谷P2066 机器分配

标签(空格分隔): 线型DP


【题目】

题目描述

总公司拥有高效设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M≤15,N≤10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。

输入格式

第一行有两个数,第一个数是分公司数N,第二个数是设备台数M。

接下来是一个N*M的矩阵,表明了第 I个公司分配 J台机器的盈利。

输出格式

第1行为最大盈利值

第2到第n为第i分公司分x台

P.S.要求答案的字典序最小

输入输出样例

输入 #1

3 3

30 40 50

20 30 50

20 25 30

输出 #1

70

1 1

2 1

3 1

【思路】

显然是个线型动归,直接蒙上(误)转移方程就行。定义f[i][j]表示第i行共分j台时的最多利润,本题与普通的线型动归的区别在于多了一维循环。

用脑子想了一想,f[i][j]要是不转移,就是a[i][j](原数据),f[i][j]要是转移,肯定是从这一行这个公司的前面k台的盈利值,上一行即此前算出的f[i-1][j-k]中转移过来,转移方程:f[i][j]=max(f[i-1][k]+a[i][j-k])(0<=k<=j)。

写的时候是要注意第二层循环总台数时需要倒序,防止重算。

至于后面的路径,跟普通的线型动归的路径记录差不多,看注释就行了。

【代码】

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=50,maxe=25,INF=0x3f3f3f3f;
int n,m,a[maxe][maxe],f[maxn][maxn],path[maxn][maxe],ans;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();
}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
int main(){
freopen("a.in","r",stdin);
n=read(),m=read();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j]=read();
}
}//普通的读入
for(int i=1;i<=n;i++){
for(int j=m;j>=1;j--){//这里我测了一下,正序倒序都可以,因为某一行某个状态的值不影响同一行其他状态的值
f[i][j]=a[i][j];//初始化
for(int k=0;k<=j;k++){//因为题目没要求没个公司必选一件,所以要从0开始
if(f[i][j]<f[i-1][k]+a[i][j-k]){//转移,严格的小于,不能等于
f[i][j]=f[i-1][k]+a[i][j-k];//上一行(这一行以上)选取k台,那这行肯定选取j-k台
path[i][j]=k;//记录路径,path[i][j]现在处于第i行,一共选取了j台,这一行选取的台数
}
}
}
}
cout<<f[n][m]<<endl;
int now=n,k=m;
int way[maxn];
while(1){
if(now==1){
way[1]=k-path[now][k];
break;
}
way[now]=k-path[now][k];
k=path[now][k];
now--;
}
for(int i=1;i<=n;i++){
cout<<i<<" "<<way[i]<<endl;
}
}

【难点】

本道题其实难点在于字典序的处理,集中表现在三个问题

1.第三层循环是否倒序

2.k代表前一行还是这一行的台数

3.path[i][j]里面存k还是j-k

1/2:

因为答案要求我们如果有相同答案,输出字典序最小的,这就要求我们第三层循环中正序循环上一行的状态,这里k代表的上一行的断点,这样最先存的路径一定是上一行字典序小的,当然路径还是应该存上一行的(要是存本行的断点第一行的数据不对,可能是没有存)。

因此,这里还可以这样写:

	for(int i=1;i<=n;i++){
for(int j=m;j>=1;j--){
f[i][j]=a[i][j];
for(int k=j;k>=0;k--){
if(f[i][j]<f[i-1][j-k]+a[i][k]){//这一行的字典序大了,上一行的才小
f[i][j]=f[i-1][j-k]+a[i][k];
path[i][j]=j-k;
}
}
}
}
cout<<f[n][m]<<endl;
int now=n,k=m;
int way[maxn];
while(1){
if(now==1){
way[1]=k-path[now][k];
break;
}
way[now]=k-path[now][k];
k=path[now][k];
now--;
}

但是但是但是但是但是,题目的数据很水,这个数据不管上面的那三个问题都能过

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

于是改了一下子数据:

3 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 4 1 1 1 1 1 1 1 1 1 1 3

正确输出:

6

1 1

2 10

3 4

这样的话第三层的循环就必须与k的含义以及是否取等对应了(即使你A了的话)


第二次写题解耗费这么长时间,溜了溜了.jpg

【线型DP】洛谷P2066 机器分配的更多相关文章

  1. 洛谷 p2066 机器分配(资源型)

    机器分配 https://www.luogu.org/problem/show?pid=2066 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定 ...

  2. [洛谷P2066]机器分配

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  3. 洛谷 P2066 机器分配

     题目背景 Background 无  题目描述 Description 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能 ...

  4. Luogu P2066 机器分配(dp)

    P2066 机器分配 题面 题目背景 无 题目描述 总公司拥有高效设备 \(M\) 台,准备分给下属的 \(N\) 个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这 \(M\ ...

  5. P2066 机器分配 解析

    小日记: 1.今天新学的字体颜色,尽管不熟悉,但玩的666,卡星(开心) ╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮╰( ̄▽ ̄)╮ 2.今天油腔滑调,谅解亿下 P2066 ...

  6. 树形DP 洛谷P2014 选课

    洛谷P2014 选课 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门 ...

  7. P2066 机器分配 DP

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  8. P2066 机器分配 (DP+DP输出)

    题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15,N≤10.分 ...

  9. luogu P2066 机器分配[背包dp+方案输出]

    题目背景 无 题目描述 总公司拥有高效设备M台,准备分给下属的N个分公司.各分公司若获得这些设备,可以为国家提供一定的盈利.问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值.其中M≤15 ...

随机推荐

  1. Linux 重装MySQL

    1.首先查看当前MySQL的安装情况,查找之前是否安装了MySQL rpm -qa|grep -i mysql 可以看到如下图: 因为我是使用的宝塔面板一键安装的LAMP,所以显示安装了bt-mysq ...

  2. Linux: 如何分割文件,不再被 4G 大小限制了

    单文件 4G 限制 FAT32 4G 限制 百度网盘超出 4G 限制 单文件分割与合并 单文件,如:archive.tar.gz 分割 split -b 3000M -d -a 1 archive.t ...

  3. @Transactional 事务的底层原理

    最近同事发现一个业务状态部分更新的bug,这个bug会导致两张表的数据一致性问题.花了些时间去查问题的原因,现在总结下里面遇到的知识点原理. 问题一:事务没生效 我们先看一段实例代码,来说明下问题: ...

  4. css3图片防止变形

    1.object-fit 由于图片原始大小都不一样,强行设定大小值会导致拉伸,如果不设定大小则参差不齐. 之前我们大多数用的 大多数都是利用background-size: cover 来避免对图片造 ...

  5. 快速升级Zabbix 5.0 版本

    Zabbix 5.0 增加了很多新功能,如:垂直菜单.隐藏菜单.用户界面中的测试项目.限制代理检查.查找并替换预处理步骤 ES7支持等等...快来部署体验一把尝鲜体验 Zabbix 5.0 吧     ...

  6. (前端)angular报错日常以及记录日常

    目录1 json的key...value问题 遍历json的key...value的时候报错: [tslint] for (... in ...) statements must be filtere ...

  7. CentOS6.5 开机启动自动运行redis服务

    [一].查找和设置自己的redis路径参数 环境变量 PATH=/usr/local/bin:/sbin/:/usr/bin:/bin 端口 REDISPORT=6379 文件位置 EXEC=/usr ...

  8. nodejs 换源

    解决npm install安装慢的问题国外镜像会很慢 可用 get命令查看registry npm config get registry 原版结果为 http://registry.npmjs.or ...

  9. git&github&Jenkins完成可持续集成

    1.安装git :想要安装Git首先要下载Git的安装包程序. Git安装包下载地址:https://git-scm.com/downloads/ 2.双击下载git安装包进入安装界面, 点击下一步, ...

  10. matplotlib作图一例

    知识点都在这个例子里面: plt.figure(figsize=(10,10)) for i in range(25): plt.subplot(5,5,i+1) plt.xticks([]) plt ...