機器分配問題
阿新 • • 發佈:2019-01-01
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]); }