机器分配-分组背包&&线性动态规划
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 21 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; }
相关文章推荐
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- 动态规划
- Android dpi,dip,dp的概念以及屏幕适配
- C++ 动态规划
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- 动态规划解决背包问题的核心思路
- DP(动态规划) 解游轮费用问题
- Android对px和dip进行尺寸转换的方法
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门