hdu 1712 分组背包

来源:互联网 发布:联通显示4g但没有网络 编辑:程序博客网 时间:2024/05/17 22:25

ACboy needs your help

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5403    Accepted Submission(s): 2937

问题描述
ACboy N这学期的课程,他打算花米天学习。 当然,他将获得的利润来自不同课程根据天他花在它。 如何安排N M天课程来最大化利润?

输入
输入包含多个数据集。 一个数据集从一行包含两个正整数N和M,N是课程的数量,M是天ACboy。
接下来跟随一个矩阵[我][j],(1 < =我< = N < = 100,< = 1 j < = < = 100)。 [我][j]表明如果ACboy花天i当然他将获得利润的价值[我][j]。
N = 0和M = 0结束输入。

输出
对于每个数据集,你的程序应该输出一行,包含ACboy将获得最大利润的数量。
样例输入
2 21 21 32 22 12 12 33 2 13 2 10 0
样例输出
346

题目大意:有n门课程,和m天时间,完成a[i][j]得到的价值为第i行j列的数字,求最大价值......

背包九讲之分组背包  

这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设f[k][v]表示前k组物品花费费用v能取得的最大权值,则有:

f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i属于组k}

使用一维数组的伪代码如下:

for 所有的组k
    for v=V..0
        for 所有的i属于组k
            f[v]=max{f[v],f[v-c[i]]+w[i]}

注意这里的三层循环的顺序,甚至在本文的第一个beta版中我自己都写错了。“for v=V..0”这一层循环必须在“for 所有的i属于组k”之外。这样才能保证每一组内的物品最多只有一个会被添加到背包中。

解题思路:先每一组组内物品求得最优,然后再组与组之间找最优;但求组内最优时需要注意,分组背包与其它的背包不同,这个需要把for j=v=V......0 放在for k=m所有的k属于m这一组的组内物品,可见上面伪代码。


具体代码:#include <stdio.h>#include <string.h>#define max(a,b) a>b?a:bint a[105],dp[105]; int main(){int n,m;while(scanf("%d%d",&n,&m)!=EOF&&n!=0&&m!=0){int i,j,k;memset(dp,0,sizeof(dp));for(i=0;i<n;i++){for(j=1;j<=m;j++)scanf("%d",&a[j]);for(j=m;j>=0;j--)for(k=1;k<=m;k++)if(j-k>=0)dp[j]=max(dp[j],dp[j-k]+a[k]);}printf("%d\n",dp[m]);}return 0;}



问题 E: 分组背包问题
时间限制: 1 Sec  内存限制: 128 MB
提交: 1  解决: 1
[提交][状态][讨论版]
题目描述

分组背包问题
有N(N<=100)件物品和一个容量为V(V<=1000)的背包。第i件物品的费用是c[i](c[i]<=100),价值是w[i](w[i]<=100)。
这些物品被划分为k(k<=n)组,每组中的物品互相冲突,最多选一件。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大.

提示:分组背包对于当前的空间组与组之间的考虑放或不放,组内成员考虑假如放的话,选一个放。

假如组数只有一组。选择放一个到背包中
for v=V..0
   for i=1..N
 f[v]=max{f[v],f[v-c[i]]+w[i]};

和01背包联系起来。可以这样思考01背包:有n组,每组只有一个物品。
01背包伪代码
for i=1..N   
    for v=V..0
        f[v]=max{f[v],f[v-c[i]]+w[i]}
输入

多组数据
第一行 物品件数n 组数k 背包容量v
第二行 k个数据 表示第j组有多少个物品
接下来每组的物品的费用 c[i] w[i]
输出

最大的价值总和
样例输入
1
10 3 10
3 3 4
1 2
2 3
3 4
4 5
5 6
7 8
8 9
1 2
2 3
3 4
样例输出
13


具体代码:#include <stdio.h>#include <string.h>#define max(a,b) a>b?a:b int c[105],w[105];int z[105],dp[105];int main(){int T;scanf("%d",&T);while(T--){int n,k,V,i;scanf("%d%d%d",&n,&k,&V);for(i=0;i<k;i++)scanf("%d",&z[i]);memset(dp,0,sizeof(dp));for(i=0;i<k;i++)//k组 {for(int j=0;j<z[i];j++)//每组的物品 scanf("%d%d",&c[j],&w[j]);for(int k=V;k>0;k--)for(int t=0;t<z[i];t++)//对组内的每个物品进行dp if(k>=c[t])dp[k]=max(dp[k],dp[k-c[t]]+w[t]);}printf("%d\n",dp[V]);}return 0;}


0 0
原创粉丝点击