1. 程式人生 > >機器分配問題

機器分配問題

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]);
}