题目
总公司拥有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
题目思路
数据范围比较小,整体来说是比较简单的。
这个题目没做出来的主要原因在于不知道如何输出方案。
在这里记录一下学习过程。
题目意思是要我们正序吧所有结果按照正序输出,而我们一般得出来的结果都是最后一层结果,所以需要修改,遍历公司的时候倒序遍历,这样的话,我们就可以通过枚举体积的变化来输出方案。
这是一种输出方案的方式,更多方式还等着我去探索。
AC代码
#include<bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define For(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(a) cout << #a << " = " << a << endl;
#define mod(x) (x) % MOD
#define ENDL "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N = 10 + 5, M = 15 + 5;
int f[N][M], w[N][M];
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false); // 取消cin与stdin 的同步
cout.tie(0), cin.tie(0);
int n, m;
cin >> n >> m;
_rep(i, 1, n) _rep(j, 1, m) cin >> w[i][j];
For(i, n, 1) _rep(j, 0, m) _rep(k, 0, j)
f[i][j] = max(f[i][j], f[i + 1][j - k] + w[i][k]);
cout << f[1][m] << ENDL;
int j = m;
_rep(i, 1, n) _rep(k, 0, j) if (f[i][j] == f[i + 1][j - k] + w[i][k]) {
cout << i << " " << k << ENDL;
j -= k;
break;
}
return 0;
}