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台}
解题思路:
水题,动态规划,
状态转移方程:
dp[i][j] = max(dp[i - 1][j - k] + profit[i][k]) ( 0<= k <= j)
dp[i][j]代表j台机子分给前i个公司的最大收益,profit[i][k]表示第i个公司分配k台的收益
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxm = 16;
const int maxn = 11;
int dp[maxn][maxm], result[maxn][maxm], n, m, profit[maxn][maxm];
void output(int x, int y);
int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
memset(dp, 0, sizeof(dp));
memset(profit, 0, sizeof(profit));
memset(result, 0, sizeof(result));
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
scanf("%d", &profit[i][j]);
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
for(int k = 0; k <= j; k++)
{
int val = dp[i - 1][j - k] + profit[i][k];
if(dp[i][j] <= val)
{
dp[i][j] = val;
result[i][j] = k;
}
}
}
}
printf("%d\n", dp[n][m]);
output(n, m);
}
return 0;
}
void output(int x, int y)
{
if(x == 0)
return;
output(x - 1, y - result[x][y]);
printf("%d %d\n", x, result[x][y]);
}

926

被折叠的 条评论
为什么被折叠?



