P2066 机器分配

题目背景

题目描述

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

输入输出格式

输入格式:

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

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

输出格式:

第1行为最大盈利值

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

输入输出样例

输入样例#1:

3 3
30 40 50
20 30 50
20 25 30

输出样例#1:

70
1 1
2 1
3 1

按照公司的顺序来分配机器,即按照公司的顺序划分阶段,第一个阶段把M台设备分给第一个公司,记录下来获得的各个盈利值,然后把M台设备分给前两个公司,和第一个阶段比较记录下来更优的各个盈利值,一直到第N个阶段把M台机器全部分给了N个公司,就可以得到最优解,下面来讨论两个阶段之间的关系,设数组F[I][J]表示前I个公司分配J台机器的最大盈利,数组F[I-1][K]表示前I-1个公司分配K台机器的最大盈利(1≤I≤N,1≤J≤M,0≤K≤J),用Value[I][J]表示第I个公司分配 J台机器的盈利, 则F[I][J]可以由下面的式子中取最大值获得: F[I-1][0]+Value[I][J] //前I-1公司分配0台机器最大盈利+第I个公司分配J台的机器的盈利 F[I-1][1]+Value[I][J-1] //前I-1公司分配1台机器最大盈利+第I个公司分配J-1台的机器的盈利 F[I-1][2]+Value[I][J-2] //前I-1公司分配2台机器最大盈利+第I个公司分配J-2台的机器的盈利 F[I-1][J-1]+Value[I][1] //前I-1公司J-1分配台机器最大盈利+第I个公司分配1台的机器的盈利 F[I-1][J]+Value[I][0] //前I-1公司分配J台机器最大盈利+第I个公司分配0台的机器的盈利   在这里用机器数用做每个阶段的状态,由于Value[I][J]的值为定值,要使前面每个式子的值最大,就必须使第i-1阶段的各个状态的值最大,阶段i的状态只能由阶段i-1中的状态通过状态转移方程求得,与其他状态没有关系。由此可见,该问题具备了最优子结构和无后效性原则,适宜使用动态程序设计方法求解。状态转移方程为:F[I][J]=MAX{F[I-1][K]+Value[I][J-K]} (1≤I≤N,1≤J≤M,0≤K≤J)   初始值:F[0][0]=0,F[n][m]的值即为所求最大盈利值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXN=30;
 6 int map[MAXN][MAXN];
 7 int f[MAXN][MAXN];// f[i][j]记录第i个公司分j台机器的最大收益 
 8 int max1;
 9 int show(int i,int j)                          //输出各分公司分配情况
10 {
11   int k;
12   if (i==0) return 0;
13   for (k=0;k<=j;k++)
14    if (max1==f[i-1][k]+map[i][j-k])          //递归求各公司分配的机器数量
15      {
16        max1=f[i-1][k];
17        show(i-1,k);
18        cout<<i<<" "<<j-k<<endl;
19        break;
20      }
21 }
22 
23 int main()
24 {
25     int n;//公司数
26     int m;//机器数
27     scanf("%d%d",&n,&m);
28     for(int i=1;i<=n;i++)
29         for(int j=1;j<=m;j++)
30             scanf("%d",&map[i][j]); 
31     for(int i=1;i<=n;i++)
32     for(int j=1;j<=m;j++)
33     {
34         for(int k=0;k<=j;k++)
35         f[i][j]=max(f[i-1][k]+map[i][j-k],f[i][j]);
36     }
37     max1=f[n][m];
38     printf("%d\n",f[n][m]);
39     show(n,m);
40     return 0;
41 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CDA数据分析师

排序在数据分析中有多重要?

说不会对数据排序的举手,所有的手都放下了。拿到数据,谁还不会排序吗?就连你在打牌时都在排序。 ? 可是这一小小的操作,在数据分析中到底有...

1866
来自专栏程序员互动联盟

【入门指导】学C语言一段时间了,还是一头雾水该咋办?

学C了一头雾水该怎么办?最简单的方法就是你再学一遍呗。俗话说熟能生巧,铁杵也能磨成针。 但是一味的为学而学,这个好像没什么卵用。为什么学了还是一头雾水,重点就在...

3877
来自专栏各种机器学习基础算法

NLTK学习笔记(二)

词意消歧 在词意消歧中,我们要算出特定上下文中的词被赋予的是哪个意思。 思考存在歧义的词 serve 和 dish: (1) a. serve: help wi...

2967
来自专栏落影的专栏

程序员进阶之算法练习(十二)

前言 题目地址在HDU,输入对应的题号即可看到题目,在百度搜索hdu+对应的题号可以看到题解。 我简单的对题目难度进行了划分: 简单题:想法题,实现简单...

3517
来自专栏AI科技大本营的专栏

谷歌大脑深度学习从入门到精通视频课程[6.1]:自动编码器——定义

AI100 已经引入 Hugo Larochelle 教授的深度学习课程,会每天在公众号中推送一到两节课,并且对视频中的 PPT 进行讲解。课后,我们会设计一...

37212
来自专栏ACM算法日常

关于如何培养算法思维的一点思考

最近收到公众号里一个同学的消息,大概意思是觉得自己做了很多题(可能是参考别人的题解),但是碰到问题还是经常没有思路,想问下如何才能正确的做题,以...

2102
来自专栏ACM算法日常

芯片测试(分治)- 例题

分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成...

1102
来自专栏程序人生 阅读快乐

算法竞赛入门经典(第2版)(算法艺术与信息学竞赛).pdf

《算法竞赛入门经典(第2版)》是一本算法竞赛的入门与提高教材,把C/C++语言、算法和解题有机地结合在一起,淡化理论,注重学习方法和实践技巧。全书内容分为12 ...

1593
来自专栏苦逼的码农

我是如何学习数据结构与算法的?

数据结构与算法的地位对于一个程序员来说不言而喻。今天这篇文章不是来劝你们学习数据结构与算法的,也不是来和你们说数据结构与算法有多重要。

2101
来自专栏数据结构与算法

博弈论进阶之Every-SG

因为两个人都顶尖聪明,因此当一个人知道某一个游戏一定会输的话,它一定会尽力缩短游戏的时间,当它知道某一个游戏一定会赢的话,一定会尽力延长游戏的时间(毕竟都是为了...

42611

扫码关注云+社区

领取腾讯云代金券