动态规划-分组背包问题

https://vjudge.net/contest/297216?tdsourcetag=s_pctim_aiomsg#problem/K

3(物品组数) 3(时间)

f[i,j]表示完成了前i件任务,
背包容量为j时所能达到的最大价值。
f[i-1,j-cost]+val;
2 1 最多选一件
2 5
3 8

2 0 至少选一件
1 0
2 1

3 2 自由选
4 3
2 1
1 1

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
const int maxn=105;
int cost[maxn];
int val[maxn];
int f[maxn][maxn];
int main()
{
    int m,t;
    while(scanf("%d%d",&m,&t)==2) // 不写==2会超时!!
    {
        memset(f,0,sizeof(f));
        for(int i=1; i<=m; i++)
        {
            int n,type;
            scanf("%d%d",&n,&type);
            for(int j=1; j<=n; j++)
                scanf("%d%d",&cost[j],&val[j]);
            if(type==0)
            {
                // 背包初始化要从0开始,而不是1
                for(int j=0; j<=t; j++) f[i][j]=-INF;
                // 将新判断的一组物品,开始时不同背包容量的价值都初始化为负数,保证至少选入这个物品。
                for(int j=1; j<=n; j++)
                    for(int k=t; k>=cost[j]; k--) // k要倒着枚举,保证不重复选取。
                    {

                        f[i][k]=max(f[i][k],f[i][k-cost[j]]+val[j]);
                        f[i][k]=max(f[i][k],f[i-1][k-cost[j]]+val[j]);
                        // 这两个写反了会错,为什么?
                    }
            }
            else if(type==1)
            {
                for(int k=0; k<=t; k++) f[i][k]=f[i-1][k];
                for(int j=1; j<=n; j++)
                    for(int k=cost[j]; k<=t; k++)// 这个k可正序也可反序枚举
                    {
                        f[i][k]=max(f[i][k],f[i-1][k-cost[j]]+val[j]);
                    }
            }
            else
            {
                //  标准1维数组优化的01背包问题,
                for(int k=0; k<=t; k++) f[i][k]=f[i-1][k];
                for(int j=1; j<=n; j++)
                    for(int k=t; k>=cost[j]; k--)
                    {
                        f[i][k]=max(f[i][k],f[i][k-cost[j]]+val[j]);
                    }
            }
        }
        int ans=max(f[m][t],-1);
        printf("%d\n",ans);
    }
}

原文地址:https://www.cnblogs.com/dongdong25800/p/10789569.html

时间: 2024-10-22 01:03:13

动态规划-分组背包问题的相关文章

HDU 1712 ACboy needs your help (分组背包问题)

有n门课程,和m天时间,完成a[i][j]得到的价值为第i行j列的数字,求最大价值...... 看过背包九讲的话,做这个就容易多了,其实就是简单的分组背包问题. #include <iostream> #include <string.h> using namespace std; int A[105][105]; int dp[105]; int main() { int n, m; while(cin>>n>>m&&n+m) { int

动态规划:背包问题

例题:装箱问题 ( http://www.wikioi.com/problem/1014/  ) 题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小. 输入描述 一个整数v,表示箱子容量,一个整数n,表示有n个物品 接下来n个整数,分别表示这n 个物品的各自体积 输出描述 一个整数,表示箱子剩余空间. 样例输入 24 6 8 3 12 7 9 7

算法导论三剑客之 动态规划 0-1背包问题

1 #include "iostream" 2 using namespace std; 3 4 float MAX(float m1,float m2){ 5 if(m1>=m2) 6 return m1; 7 else 8 return m2; 9 } 10 11 float bag_Zero_One(int n,float v,float p[],float w[]){ 12 if(n==0||v==0) 13 return 0; 14 else{ 15 float m2;

背包九讲之六(分组背包问题)

1 /* 2 有n件物品和一个容量为v的背包,第i件物品的费用是c[i],价值是w[i] 3 这些物品被分为若干组,每组中的物品互相冲突,即一组中只能取一件物品 4 将哪些物品装入背包使得总价值最大 5 dp[k][v] 表示前k组物品花费容量v能取到的最大值 6 dp[k][v] = max(dp[k-1][v],dp[k-1][v-c[i]]+w[i])//物品i属于第k组 7 for(i=1; i<=k; ++i) 8 for(j=v;j>=0; ++j) 9 for(所有的l属于组k)

动态规划——0-1背包问题

 0-1背包问题: 描述:给定n中物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为c,问应如何选择装入背包中的物品,使得装入背包中的物品总价值最大? 0-1背包问题是一个特殊的整数规划问题. 设所给0-1背包问题的子问题; 其最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,-,n时0-1背包问题的最优值.由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下: NO1:递归实现 1 /* 2 *Description 递归实现 3 *设有一

动态规划01背包问题

动态规划0-1背包问题 ? 问题描写叙述: 给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问应怎样选择装入背包的物品,使得装 入背包中物品的总价值最大? ? 对于一种物品,要么装入背包,要么不装.所以对于一种物品的装入状态能够取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题. 过程分析 数据:物品个数n=5,物品重量w[n]={0,2,2,6,5,4},物品价值V[n]={0,6,3,5,4,6}, (第0位,置为0,不參与计算,仅

分组背包问题描述与实现

#include <stdio.h> int w[301][21]; int get_max(int a, int b) { if(a>=b) return a; else return b; } int main(void) { int tc, T; setbuf(stdout, NULL); int Amout = 0; int company_num = 0; int i,j,k; scanf("%d", &T); for(tc = 0; tc <

AC_9. 分组背包问题

代码: //9. 分组背包问题 //多重背包问题是分组背包问题的一个特殊情况 /* 每个组的物品有s+1种选择 for(int i = 0;i<n;i++) { for(int j = m;j>=v;j--) { dp[j] = max{dp[j],dp[j-v[0]]+w[0],dp[j-v[i]]+w[i],.....,dp[j - v[s-1]] + w[s-1]}; } } dp[m] */ #include<iostream> #include<cstring>

动态规划之背包问题

背包问题是一个经典的算法问题,可以用动态规划,贪心法,分支界限法等方法解决.问题描述:有n个物品,编号1,2,3,..n,其中第 i 个物品重量为Wi 价值 Vi ,有一个容量为W的背包.在容量允许范围内,如何选择物品,可以得到最大的价值.(为了简单起见,假设物品的重量 Wi 和价值Vi 都是正数) 今天主要说的是0.1背包问题,解法是动态规划.当然,对于另外两种问题也会有所介绍. 问题分析: 用动态规划解问题首先要有效的找出子问题,可以通过这个子问题得推得原问题的解,通常子问题的实质是和原问题