机器分配

Description

总公司拥有高效设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为国家提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。其中M≤15,N≤10。分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。 

Input

输入数据文件格式为:第一行有两个数,第一个数是分公司数N,第二个数是设备台数M。 
接下来是一个N*M的矩阵,表明了第 I个公司分配 J台机器的盈利。

Output

输出第一行为最大盈利值; 
接下来有n行,分别为各分公司分配的机器数。

Sample Input

 3 3

30 40 50 

20 30 50

20 25 30

Sample Output

70                                                                       {最大盈利值为70}
1 1                                                                     {第一分公司分1台}
2 1                                                                     {第二分公司分1台}
3 1                                                                     {第三分公司分1台}
复制代码
/*
  f[i][j]表示前i个公司分配j台机器的最大效益
  当我们当前面临前i个公司分配j台机器,就要让第i个分配k台,前i-1个分配j-k台, 
  于是得到状态转移方程:
      f[i][j]=max(f[i][j],f[i-1][j-k]+a[i][k])
*/ 
#include<cstdio>
#include<cstring>
#include<iostream>
#define M 20
using namespace std;
int f[M][M],a[M][M],ans[M];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
          scanf("%d",&a[i][j]);
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        for(int k=0;k<=j;k++)
          f[i][j]=max(f[i][j],f[i-1][j-k]+a[i][k]);
    printf("%d
",f[n][m]);
    int tot=f[n][m],p=n,p2=m;
    while(1)
    {
        if(p==0)break;
        for(int i=p2;i>=0;i--)
          if(a[p][i]+f[p-1][p2-i]==tot)
          {
              ans[p]=i;
              tot-=a[p][i];
              p--;
              p2-=i;
              break;
          }
    }
    for(int i=1;i<=n;i++)
      printf("%d %d
",i,ans[i]);
    return 0;
}
View Code


原文地址:https://www.cnblogs.com/harden/p/5617979.html