#分组背包 #背包方案 ——Acwing 1013 机器分配

总公司拥有M台 相同 的高效设备,准备分给下属的N个分公司。

各分公司若获得这些设备,可以为国家提供一定的盈利。盈利与分配的设备数量有关。

问:如何分配这M台设备才能使国家得到的盈利最大?

求出最大盈利值。

分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。

输入格式
第一行有两个数,第一个数是分公司数N,第二个数是设备台数M;

接下来是一个N*M的矩阵,矩阵中的第 i 行第 j 列的整数表示第 i 个公司分配 j 台机器时的盈利。

输出格式
第一行输出最大盈利值;

接下N行,每行有2个数,即分公司编号和该分公司获得设备台数。

答案不唯一,输出任意合法方案即可。

数据范围
1≤N≤10 ,
1≤M≤15
输入样例:
3 3
30 40 50
20 30 50
20 25 30
输出样例:
70
1 1
2 1
3 1

#include<bits/stdc++.h>
using namespace std;
const int N = 11, M = 16;
int f[N][N], w[N][N], n, m, ans[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 ++)
            for(int k = 0; k <= j; k ++)
                f[i][j] = max(f[i][j], f[i- 1][j - k] + w[i][k]);
                
    cout << f[n][m] << endl;
	/*1——————————*/
    int vol = m;
    for(int i = n; i >= 1 ; i--)
        for(int j = 0; j <= vol; j ++)
            if(f[i][vol] == f[i - 1][vol - j] + w[i][j]){
                ans[i] = j;
                vol -= j;
                break;
            }
            
    for(int i = 1;i <= n; i ++)
        cout << i << " " << ans[i] << endl;
        return 0;
}



文意理解 : 将 M 个机器(一样的) 分配给 N 个公司,
每个公司对应的会产生 w[ n ][ m ] 的收入,
目的: 使得收入最大化。

将每一个公司看做一个组, 里面的 收入只可以 用 对用数量的机器选择一个。
那么机器数量就可以理解为体积,对应的 w[ i ][ j ] 是价值。
*1 ————————
将状态进行比较,
如果f[ i ][ vol ] 满足 f[i - 1][vol - j] + w[ i ][ j ] ,
则可以认为,f[ i ][ vol ]是由 f[i - 1][vol - j] 转化过来的,
也就是 f[i - 1][vol - j] 是 f[ i ][ vol ] 的上一步,
中间差的 w[ i ][ j ] 即认为 在这一步 我们选择了 w[ i ][ j ],
那么 ans[ i ] = j;

原文地址:https://www.cnblogs.com/yuanyulin/p/14026767.html