题解 P2066 【机器分配】
分析
显然是一个经典的dp题目。我们定义一个数组:f[i][j]表示前i个公司分配j台机器的最大盈利。那么求解f[i][j]的过程应该怎么求解呢?首先,我们在给第i个公司分配机器的时候,我们肯定为第i-1个公司分配过机器了,所以显然,i的状态由j的状态推导而来,那么我们需要怎么枚举呢?就是:通过枚举i个公司需要多少台机器,再枚举i-1个公司需要多少机器,再找出最大值就可以了。下面上代码:
代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int num=0;
char c=getchar();
for(;c<'0'||c>'9';c=getchar());
for(;c>='0'&&c<='9';c=getchar())num=num*10+c-'0';
return num;
}//快读
int n,m,f[30][30],value[30][30],maxl;
/*以上是变量说明阶段。
f数组:f[i][j]表示前i个公司分j台机器的最大盈利
value数组:value[i][j]表示第i个公司分j台机器的盈利
*/
int print(int i,int j)
{
if(i==0)return 0;
for(int k=0;k<=j;k++)
//k枚举了前i-1个分公司分得多少机器
if(maxl==f[i-1][k]+value[i][j-k])
//知道结果倒推回去
{
maxl=f[i-1][k];//步步为营的方式
print(i-1,k);//继续低柜求解
printf("%d %d\n",i,j-k);//倒序输出
break;//搜到了直接跳出循环
}
}
int main()
{
n=read();
m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
value[i][j]=read();
//读入各种数据
for(int i=1;i<=n;i++)//枚举公司数
for(int j=1;j<=m;j++)//枚举机器数(总)
{
maxl=0;
for(int k=0;k<=j;k++)//枚举前i-1个公司分到的机器数
if(f[i-1][k]+value[i][j-k]>maxl)
/*f[i-1][k]:前i-1个公司分k台机器的利润
value[i][j-k]:第i个公司分j-k台机器的利润
加起来是i个公司分j台机器的最大利润*/
maxl=f[i-1][k]+value[i][j-k];
f[i][j]=maxl;
}
printf("%d\n",f[n][m]);//输出结果
print(n,m);//输出分配方案
return 0;
}