您的位置:首页 > 其它

机器分配-分组背包&&线性动态规划

2016-07-23 19:07 344 查看

题目描述

某总公司拥有高效生产设备M台,准备分给下属的N个分公司。各分公司若获得这些设备,可以为总公司提供一定的盈利。问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。 分配原则:每个公司有权获得任意数目的设备,但总台数不得超过总设备数M。其中M<=100,N<=100。

输入

第一行为两个整数M,N。接下来是一个N×M的矩阵,其中矩阵的第i行的第j列的数Aij表明第i个公司分配j台机器的盈利。所有数据之间用一个空格分隔。

输出

只有一个数据,为总公司分配这M台设备所获得的最大盈利。

样例输入

3 2
1 2 3
2 3 4

样例输出

4
解题思路
解法一(线性dp):每个公司只能选一种分配方式,使用线性dp,前 i 个公司分配 j 个机器的最大利润等于前i-1个公司的各种状态下分配给第i个公司k个机器的最大值。
解法二(分组背包):第k个公司分i台机器当成物品,那么一共有n*m个物品。一个公司的分配1-m台机器的m种情况当成一组物品,这一组物品相互排斥,要么选一个要么不选,符合分组背包的特点。分i台机器,消耗i个体积,获得的价值就是公司盈利,背包容量就是总共的m台机器。这里提供一维和二维两种存dp的代码。
解法一代码
#include<cstdio>
#include<iostream>
using namespace std;
int a[110][110];
int f[110][110];//f表示前i个公司分配j个机器所获得的最大利益
int main()
{
int m,n,i,j,k;//k表示给第i个公司分配k个机器
scanf("%d%d",&m,&n);
for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
scanf("%d",&a[i][j]);
}

for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
{
for(k=0;k<=j;++k)//由哪种状态分配给第i公司k个机器,使得前i个公司分配得到j个机器f[i][j]的值最大
{
if(f[i-1][j-k]+a[i][k]>f[i][j])
f[i][j]=f[i-1][j-k]+a[i][k];
}
}
}
printf("%d",f
[m]);
return 0;
}


解法二代码1(1维数组存最大价值,可以先看下面2维的理解一下):

#include <iostream>
#include <cstdio>

using namespace std;

bool vist[110][110];
int main()
{
int n,m,i,j;//m台机器表示背包容量
int v[101][101]={0};//每个公司分几个机器的利益表示物品价值
int dp[110]={0};//这里初始化的时候 int p[110]={};括号里不写值是不对的!!

scanf("%d%d",&m,&n);

for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
scanf("%d",&v[i][j]);//i件物品的价值
}

int k;//k组,一个公司一组
for(k=1;k<=n;++k)
for(j=m;j>=0;--j)//前【k】个公司分【j】个机器 j相当于体积v
for(i=0;i<=m;++i)//给第k个公司分i个机器,i属于组k
if(j>=i && dp[j]< dp[j-i]+v[k][i])//前k-1个公司要少分i个机器,才能给第k个公司分配i个机器
dp[j]=dp[j-i]+v[k][i];

printf("%d",dp[m]);
return 0;
}


解法二代码2(2维数组存最大价值):

我写的有错误,求大神们找bug。。。。
终于找到bug了,数组v定义的时候应该开>100的,因为我的数组从v【1,1】开始的。。。
#include <iostream>
#include <cstdio>
using namespace std;

int v[110][110]={0}; //v表示价值
int dp[110][110]={0};

int main()
{
int n,m,i,j;//m表示背包容量

scanf("%d%d",&m,&n);

for(i=1;i<=n;++i)
{
for(j=1;j<=m;++j)
scanf("%d",&v[i][j]);//i件物品的价值
}
int k;
for(k=1;k<=n;++k)
for(j=m;j>=0;--j)
{
int temp=dp[k-1][j];
for(i=0;i<=j;++i)
{
if(dp[k-1][j-i]+v[k][i]>temp)
temp = dp[k-1][j-i]+v[k][i];
}
dp[k][j]=temp;
}

printf("%d",dp
[m]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 dp