DP - 分組揹包求具體方案 - 機器分配

DP - 分組揹包求具體方案 - 機器分配

總公司擁有M臺 相同 的高效設備,準備分給下屬的N個分公司。

各分公司若獲得這些設備,可以爲國家提供一定的盈利。盈利與分配的設備數量有關。

問:如何分配這M臺設備才能使國家得到的盈利最大?

求出最大盈利值。

分配原則:每個公司有權獲得任意數目的設備,但總檯數不超過設備數M。

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

接下來是一個N*M的矩陣,矩陣中的第 i 行第 j 列的整數表示第 i 個公司分配 j 臺機器時的盈利。

輸出格式
第一行輸出最大盈利值;

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

答案不唯一,輸入任意合法方案即可。

數據範圍
1≤N≤10,
1≤M≤15

輸入樣例:
3 3
30 40 50
20 30 50
20 25 30
輸出樣例:
70
1 1
2 1
3 1

分析:

m<=>n<=>ij<=>ij將機器總量m<=>揹包容量,公司總量n<=>可選物品總量,\\第i個公司對j臺設備的收益<=>第i種物品中體積爲j的物品的收益。

這樣,問題就轉化爲分組揹包問題,考慮每種物品選哪個的問題。

代碼:

#include<iostream>
#include<algorithm>

using namespace std;

const int N=20;

int n,m,f[N][N],w[N][N];
int cnt[N];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>w[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]+w[i][k]);
                
    cout<<f[n][m]<<endl;
    
    int V=m;
    for(int i=n;i;i--)
        for(int k=0;k<=V;k++)
            if(f[i][V]==f[i-1][V-k]+w[i][k])
            {
                cnt[i]=k;
                V-=k;
                break;
            }
            
    for(int i=1;i<=n;i++) cout<<i<<" "<<cnt[i]<<endl;
    
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章