1013. 机器分配

题目链接

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

解题思路

分组背包

将分公司当作组别,即从组别中选择一个,即分组背包问题,关键在于如何反推出路径,可利用状态转移方程逆向转移,dfs逆向从最后一个点推向第一个点

  • 时间复杂度:\(O(n\times m^2)\)

代码

// Problem: 机器分配
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/1015/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

int n,m,f[15][20],a[15][20],res[15];
void dfs(int x,int y)
{
	if(!x||y<=0)return ;
	int t=0;
	for(int j=0;j<=y;j++)
		if(f[x-1][y-j]+a[x][j]==f[x][y])
		{
		    res[x]=j;
		    dfs(x-1,y-j);
		    return ;
		}
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)
    		cin>>a[i][j];
    
    for(int i=1;i<=n;i++)
    	for(int j=0;j<=m;j++)
    	{
    	    f[i][j]=f[i-1][j];
    	    for(int k=1;k<=m;k++)
    		    if(j>=k)
    				f[i][j]=max(f[i][j],f[i-1][j-k]+a[i][k]);
    	}
    	
    dfs(n,m);
    cout<<f[n][m]<<'\n';
    for(int i=1;i<=n;i++)
    	cout<<i<<' '<<res[i]<<'\n';
    return 0;
}
posted @ 2022-03-03 15:38  zyy2001  阅读(38)  评论(0编辑  收藏  举报