HDU 3535 【背包】

题意:

给出n组数据,每组数据有一个类型。

0代表至少选择一个,1代表至多选择一个,2代表任意选择。

给出背包容量。

如果背包不能满足最基本的要求输出-1。

思路:

背包问题变相考察~

当0的时候初始化为-INF,然后就能保证至少选择一个。

当1或2的时候初始化上一层的值,然后1和2稍微有点区别,1只能从上一层得到下一层,2可以用本层更新。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int c[105],w[105];
int dp[105][105];
int main()
{
    int n,t;
    while(scanf("%d%d",&n,&t)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int m,s;
            scanf("%d%d",&m,&s);
            for(int j=1;j<=m;j++)
            {
                scanf("%d%d",&w[j],&c[j]);
            }
            if(s==0)
            {
                for(int j=0;j<=t;j++)
                {
                    dp[i][j]=-999999999;
                }
                for(int j=1;j<=m;j++)
                {
                    for(int k=t;k>=w[j];k--)
                    {
                        //dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+c[j]);
                        //dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+c[j]);
                        dp[i][k]=max(dp[i][k],max(dp[i-1][k-w[j]]+c[j],dp[i][k-w[j]]+c[j]));
                    }
                }
            }
            else if(s==1)
            {
                for(int j=0;j<=t;j++)
                {
                    dp[i][j]=dp[i-1][j];
                }
                for(int j=1;j<=m;j++)
                {
                    for(int k=t;k>=w[j];k--)
                    {
                        dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+c[j]);
                    }
                }
            }
            else
            {
                for(int j=0;j<=t;j++)
                {
                    dp[i][j]=dp[i-1][j];
                }
                for(int j=1;j<=m;j++)
                {
                    for(int k=t;k>=w[j];k--)
                    {
                        dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+c[j]);
                    }
                }
            }
        }
        if(dp[n][t]<0)
            printf("-1\n");
        else
            printf("%d\n",dp[n][t]);
    }
}
时间: 2024-12-09 02:46:32

HDU 3535 【背包】的相关文章

hdu 3535 背包综合题

1 /* 2 有n组背包,每组都有限制 3 0.至少选一项 4 1.最多选一项 5 2.任意选 6 */ 7 #include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 using namespace std; 11 12 const int maxn=105; 13 const int INF=0xfffffff; 14 int dp[maxn][maxn];//第i组,剩余时间j的最大价值 15 i

HDU 3535 背包综合

题意:给3种背包,一种是至少装一个,一种是最多装一个,一种任意. 首先要对一维状态的原始背包很熟悉才可以.此处的i代表滚动的背包类型. 1. 任意的话就是01背包  初始化:dp[i][j]=dp[i-1][j].           dp[i][j]=max{dp[i][j]  ,  dp[i][ j-w[i] ]+v[i]    } dp[i][j-w[i]] 存在. 2. 最多装一个,就是比较替换.初始化:dp[i][j]=dp[i-1][j].   dp[i][j]=max{  dp[i

hdu 4381 背包

http://acm.hdu.edu.cn/showproblem.php?pid=4381 Problem Description There are n boxes in one line numbered 1 to n, at the beginning, all boxes are black. Two kinds of operations are provided to you: 1 ai xi :You can choose any xi black boxes in interv

HDU 3535 分组混合背包

http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n组工作,T时间,每个工作组中有m个工作,改组分类是s,s是0是组内至少要做一件,是1时最多做一件,2时随意,每项工作的描述是花费的时间和获得的快乐值,求在T时间内可获的最大快乐值. memset放错位置了,折腾老半天. 分组混合背包,有的取一件或不取,有的随意,有的最少一个 分三种情况讨论 s==0 考虑前面取过时这次取或不取,前一组取过时这次取或不取 s==1 考虑前一组取过时这次取或不取

[HDU 3535] AreYouBusy (动态规划 混合背包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n个任务集合,需要在T个时间单位内完成.每个任务集合有属性,属性为0的代表至少要完成1个,属性为1的为至多完成1个,属性为2的为任意完成. 每个任务做完后都有个价值,问在T个时间单位内完成n个任务集合的任务获得的最大价值是多少?如果不能满足要求输出-1 首先先分析什么情况下输出-1: 因为属性为0的代表至少要完成1个,当遇到一个属性为0的任务集合里一个都无法完成的时候,输出-1. 其他

hdu 3535 AreYouBusy 混合背包

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有三种任务,至少完成一个,至多完成一个,任意完成.现在给出k组任务,每组任务都属于三种任务的一种.每个任务都会消耗时间,获得幸福感.求时间T内的最大满足感. 三种背包的混合.还是考察对背包问题的理解.显然一维已经满足不了要求了,我们设d[k][j]代表第k组容量为j时获得的最大满足感. 可以明显比较出三种背包的区别.(任意取也就是01背包) 任意取,至少取一种的区别:只取一种的状态是否非

HDU 3535 AreYouBusy (混合背包)

题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下,可以得到的最大的乐趣是多少,如果不能满足条件就输出-1 题解:二维01背包 dp[i][j]:前i组物品我们拥有j的价值时最大可获得的乐趣 0:我们需要先把dp[i]所有赋值为负无穷,这样就只能最少选一个才能改变负无穷 1:我们不需要:dp[i][j-ci]+gi(在此组中再选一个),这样就一定最

HDU - 3535:AreYouBusy (分组背包)

题意:给你n个工作集合,给你T的时间去做它们.给你m和s,说明这个工作集合有m件事可以做,它们是s类的工作集合(s=0,1,2,s=0说明这m件事中最少得做一件,s=1说明这m件事中最多只能做一件,s=2说明这m件事你可以做也可以不做).再给你ci和gi代表你做这件事要用ci的时间,能获得gi的快乐值.求在T的时间内你能获得的最大快乐值. 思路:分三类各自求即可.0的时候必须更新,1的时候最多更新一次,2的时候正常01背包. #include<bits/stdc++.h> #define s

HDU 3535 AreYouBusy(组合背包)

传送门 AreYouBusy Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4362    Accepted Submission(s): 1761 Description Happy New Term!As having become a junior, xiaoA recognizes that there is not much