其他分享
首页 > 其他分享> > 【ACWing】1013. 机器分配

【ACWing】1013. 机器分配

作者:互联网

题目地址:

https://www.acwing.com/problem/content/1015/

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

输入格式:
第一行有两个数,第一个数是分公司数 N N N,第二个数是设备台数 M M M;接下来是一个 N ∗ M N*M N∗M的矩阵,矩阵中的第 i i i行第 j j j列的整数表示第 i i i个公司分配 j j j台机器时的盈利。

输出格式:
第一行输出最大盈利值;接下 N N N行,每行有 2 2 2个数,即分公司编号和该分公司获得设备台数。答案不唯一,输入任意合法方案即可。

数据范围:
1 ≤ N ≤ 10 1≤N≤10 1≤N≤10
1 ≤ M ≤ 15 1≤M≤15 1≤M≤15

可以想象这 N N N个公司是 N N N组不同的物品,每组物品里有 M M M个不同的物品,体积分别是 1 , 2 , . . . , M 1,2,...,M 1,2,...,M,并且有不同的价值。那么可以看成是分组背包问题,在总体积限制是 M M M的情况下求最大价值。关于分组背包问题的思路,参考https://blog.csdn.net/qq_46105170/article/details/113845540。求方案的时候,只需逆着推一遍即可。代码如下:

#include <iostream>
using namespace std;

const int N = 11, M = 16;
int n, m;
int w[N][M];
int f[N][M];
int way[N];

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> w[i][j];

    for (int i = 1; i <= n; i++)
        for (int j = 0; j <= m; j++) {
        	// 枚举第i组物品不选的情形
            f[i][j] = f[i - 1][j];
            // 枚举第i组物品选第k个的情形,其实每个物品的体积就是k
            for (int k = 1; k <= j; k++) {
                f[i][j] = max(f[i][j], f[i - 1][j - k] + w[i][k]);
            }
        }

    cout << f[n][m] << endl;

    for (int i = n, j = m; i >= 1; i--) 
        for (int k = 0; k <= j; k++)
            if (f[i][j] == f[i - 1][j - k] + w[i][k]) {
                way[i] = k;
                j -= k;
                break;
            }

    for (int i = 1; i <= n; i++) 
        printf("%d %d\n", i, way[i]);

    return 0;
}

时空复杂度 O ( N M ) O(NM) O(NM)。

标签:分公司,机器,10,int,1013,物品,15,设备,ACWing
来源: https://blog.csdn.net/qq_46105170/article/details/114286925