每日一更:两道dp
由于今天下午要去打球,今晚可能要吃到很晚,所以下午就先更两道很简单的dp,明天再学其他的。
P2066 机器分配
题目描述
总公司拥有高效设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M ≤ 15,N ≤ 10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。
输入格式
第一行有两个数,第一个数是分公司数N,第二个数是设备台数M。
接下来是一个N*M的矩阵,表明了第 I个公司分配 J台机器的盈利。
输出格式
第1行:最大盈利值
第2到第n行:第i分公司分x台
P.S.要求答案的字典序最小
输入输出样例
输入
3 3
30 40 50
20 30 50
20 25 30
输出
70
1 1
2 1
3 1
洛谷:p2066[机器分配]
分析:
这道题属于最基础的动态规划,先按题目要求,输入一个n * m的矩阵,第 i 行 j 列的元素a[i][j]的含义是第 i 个公司,若被分得了 j 台机器,则本公司盈利为a[i][j]。所以我们要用 dp 的思想,已知我们有 m 台机器需要分配,先遍历求得每个公司在如果总共分配给所有公司 j 台机器的情况下,其公司在分得0 ~ j台机器时,所有公司获得对应的盈利dp[i][j]。
状态转移方程:dp[i][j] = dp[i - 1][u] + a[i][j - u],u的含义是在总体分配到j台机器,并能获得最大利益的情况下,前 i - 1 个公司所被分配的机器总数;所以,j - u 的含义是第 i 个公司被分配的机器数。并用 p[i][j] = j - u 来记录前 i 个公司被分配到1 ~ j 台时,第 i 个公司被分配到的机器数(盈利最大的情况下),最后dp[n][m]即为所有公司分配到m台机器时的最大盈利。
接着,用b[i]表示第i个公司被分配到的机器数,从n ~ 1遍历,即得到在我们取dp[n][m]时,每个公司应该被分配的机器数,遍历过程中用s来表示前 i - 1 个公司被分配到的总机器数,最后遍历 b 数组并输出结果即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int a[20][20], dp[20][20], p[20][20], b[20];
int read(){
int x, f = 1;
char ch;
while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
x = ch - '0';
while(ch = getchar(), ch