AcWing 1013. 机器分配 (分组背包)

1013. 机器分配

题意

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

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

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

求出最大盈利值。

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

思路

分组背包裸题

状态表示: f [ i ] [ j ] f[i][j] f[i][j] 表示分配到前 i i i 个公司 已经分配了 j j j 台机器的利润最大值

状态计算:

k k k 表示给当前公司分配 k k k 台机器

k ∈ [ 1 , j ] k \in [1,j] k[1,j]

不给当前公司分配机器: f [ i ] [ j ] = f [ i − 1 ] [ j ] f[i][j] = f[i - 1][j] f[i][j]=f[i1][j]

给当前公司分配 k k k 台机器: f [ i ] [ j ] = f [ i − 1 ] [ j − k ] + w [ i ] [ k ] f[i][j] = f[i - 1][j - k] + w[i][k] f[i][j]=f[i1][jk]+w[i][k]

最后取 m a x max max 即可

注意:需要输出具体方案 所以我们求 f [ i ] [ j ] f[i][j] f[i][j] 时从后往前求 这样的到的方案字典序最小

虽然这题没要求输出字典序

代码

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define mod 998244353
#define endl '\n'
#define int long long
using namespace std;
inline int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
inline int lowbit(int x) { return x & -x; }


typedef long long LL;
typedef pair<int, int>PII;
const int N = 1010;

int n, m;
int w[N][N];
int f[N][N];
int res[N];

void solve() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			scanf("%lld", &w[i][j]);
		}
	}
	//前 i 个公司 分配 j 个机器的 利润最大值
	for (int i = n; i >= 1; --i) {
		for (int j = 1; j <= m; ++j) {
			f[i][j] = f[i + 1][j];
			for (int k = 1; k <= m; ++k) {
				if (j - k >= 0)
					f[i][j] = max(f[i][j], f[i + 1][j - k] + w[i][k]);
			}
		}
	}


	cout << f[1][m] << endl;
	int ans = m;
	for (int i = 1; i <= n; ++i) {
		for (int k = 1; k <= m; ++k) {
			if (ans >= k && f[i][ans] == f[i + 1][ans - k] + w[i][k]) {
				res[i] = k;
				ans -= k;
				break;
			}
		}
	}
	
	for (int i = 1; i <= n; ++i)
		printf("%lld %lld\n", i, res[i]);
}

	


signed main() {
	//int t; cin >> t;
	//while(t--)
	solve();

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zzqwtc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值