第九章 動態規劃-1266:【例9.10】機器分配

【題目描述】
總公司擁有高效設備M臺,準備分給下屬的N個分公司。各分公司若獲得這些設備,可以爲國家提供一定的盈利。問:如何分配這M臺設備才能使國家得到的盈利最大?求出最大盈利值。其中M≤15,N≤10。分配原則:每個公司有權獲得任意數目的設備,但總檯數不超過設備數M.

【輸入】
第一行有兩個數,第一個數是分公司數N,第二個數是設備臺數M;

接下來是一個N*M的矩陣,表明了第 I個公司分配 J臺機器的盈利。

【輸出】
第一行輸出最大盈利值;

接下N行,每行有2個數,即分公司編號和該分公司獲得設備臺數。

【輸入樣例】
3 3 //3個分公司分3臺機器
30 40 50
20 30 50
20 25 30

【輸出樣例】
70 //最大盈利值爲70
1 1 //第一分公司分1臺
2 1 //第二分公司分1臺
3 1 //第三分公司分1臺


思路:按公司順序分配機器,第一個階段把M臺設備分配給第一個公司,記錄下獲得的各個盈利,然後把M臺設備分給前兩個公司,和第一個階段比較記錄下來更優各個盈利值,一直到第N個階段把M臺機器全部分給了N個公司。兩個階段之間關係如下討論。
f[i-1][k] 表示前i-1個公司分配k臺機器的最大盈利,用c[i][j] 表示第i個公司分配j臺機器盈利
f[i-1][0]+c[i][j] //前i-1公司分配0臺機器最大盈利+第i個公司分配j臺機器的盈利。
f[i-1][1]+c[i][j-1] //前i-1公司分配1臺機器最大盈利+第i個公司分配j-1臺機器的盈利。
f[i-1][2]+c[i][j-2] //前i-1公司分配2臺機器最大盈利+第i個公司分配j-2臺機器的盈利。



f[i-1][j-1]+c[i][1] //前i-1公司分配j-1臺機器最大盈利+第i個公司分配1臺機器的盈利。
f[i-1][j]+c[i][0] //前i-1公司分配j臺機器最大盈利+第i個公司分配0臺機器的盈利。
狀態轉移方程:F[i][j]={F[i-1][k]+c[i][j-k] } ,初值f[0][0]=0.

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 5000
using namespace std;
int f[N][N];
int n, m, ans;
int c[N][N];
 
void print(int i, int j)//打印分配情況
{
    if(i==0) return;
    for(int k = 0; k <= j; k++) {
        if(ans == f[i-1][k] + c[i][j-k]) {
            ans = f[i-1][k];
            print(i-1, k);
            printf("%d %d\n", i, j-k);
            break;
        }
    }
}
 
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) 
		scanf("%d", &c[i][j]);
    for(int i = 1; i <= n; i++) 
        for(int j = 1; j <= m; j++) {
            int maxx = 0;
            for(int k = 0; k <= j; k++) {//遞歸求各公司分配機器數量
                maxx = max(f[i-1][k] + c[i][j-k], maxx); 
            }
            f[i][j] = maxx;
        }
    printf("%d\n", f[n][m]);
    ans = f[n][m];
    print(n, m);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章