UESTC 424 AreYouBusy

混合三种背包问题。

定义:dp[i][k]表示体积为k的时候,在前i堆里拿到的最大价值。

第一类,至少选一项,dp初值全赋为负无穷,这样才能保证不会出现都不选的情况。
dp[i][k] =
max(dp[i][k],max(dp[i-1][k-c]+g,dp[i][k-c]))
其中:

dp[i][k]是不选当前项
dp[i-1][k-c]+g是表示第一次选这组的物品
dp[i][k-c]+g表示选择当前物品,并且不是第一次选。

第二类最多选一个,一旦选则是第一次选
dp[i][k] =
max(dp[i][k],dp[i-1][k-c]+g);
注意全局最优解,需复制上一组解到这一组。

第三类,无限制,则跑一个01背包
dp[i][k] = max(dp[i][k],dp[i][k-c]+g)
注意仍需复制上一组解。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 10007

int dp[N][107];
int c,g;

int Max(int k1,int k2,int k3)
{
return max(max(k1,k2),k3);
}

int main()
{
int n,T,i,j,k;
int m,s,set;
while(scanf("%d%d",&n,&T)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d%d",&m,&s);
if(s == 0) //至少选一项
{
for(j=0;j<=T;j++)
dp[i][j] = -Mod;
for(j=0;j<m;j++)
{
scanf("%d%d",&c,&g);
for(k=T;k>=0;k--)
{
int t1 = dp[i][k]; //不选择此工作
int t2 = -Mod;
int t3 = -Mod;
if(k >= c)
{
t2 = dp[i-1][k-c] + g; //第一次选此工作
t3 = dp[i][k-c] + g; //选择并且不是第一次选
}
dp[i][k] = Max(t1,t2,t3);
}
}
}
else if(s == 1) //最多选一项
{
for(j=0;j<=T;j++)
dp[i][j] = dp[i-1][j]; //由上一堆推来
for(j=0;j<m;j++)
{
scanf("%d%d",&c,&g);
for(k=T;k>=0;k--)
{
int t1 = dp[i][k];
int t2 = -Mod;
if(k >= c)
t2 = dp[i-1][k-c] + g;
dp[i][k] = max(t1,t2);
}
}
}
else if(s == 2) //随便选
{
for(j=0;j<=T;j++)
dp[i][j] = dp[i-1][j];
for(j=0;j<m;j++)
{
scanf("%d%d",&c,&g);
for(k=T;k>=c;k--)
{
dp[i][k] = max(dp[i][k],dp[i][k-c]+g);
}
}
}
}
printf("%d\n",max(dp[n][T],-1));
}
return 0;
}

UESTC 424 AreYouBusy

时间: 2025-01-02 02:48:58

UESTC 424 AreYouBusy的相关文章

2016 UESTC ACM Summer Training Team Selection (2)解题报告

总体来说,个人英语水平还太蹩脚,此次大部分时间都花在理解题意上了,而且到最后有些题目的意思还是不理解,orz... 链接→2016 UESTC ACM Summer Training Team Selection (2)  Problem A Popular Vote Accept: 0    Submit: 0 Time Limit: 2000 mSec  Problem Description In an election with more than two candidates, it

UESTC 电子科大专题训练 数据结构 D

UESTC 1584 题意:平面坐标上有n个怪物,每个怪物有一个rank值,代表x坐标和y坐标都不大于它本身的怪物数(不包括本身) 思路:对x y坐标从小到大排序,x优先排序,用数状数组计算y坐标小于它的数量 AC代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #i

UESTC 31 饭卡(Card) --背包问题

背包问题. 思路:如果m<5,此时也不能消费,所以此时答案为m m>=5: 求出背包容量为m-5,买前n-1样便宜的菜(排个序)的最大价值(即最大消费,即消费完后剩余值最接近5)最后减去最大的那个菜的价格,就得到最小的余额. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using n

UESTC 电子科大专题训练 数据结构 A

UESTC 1591 题意:求区间极值之差 思路:线段树裸题,不带更新 ACA代码: #include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "ma

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

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

2017 UESTC Training for Data Structures

2017 UESTC Training for Data Structures A    水,找区间极差,RMQ怼上去. #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;i<=b;i++) #define per(i,b,a) for (int i=b;i&

UESTC - 878 温泉旅店 二维费用背包问题

http://acm.uestc.edu.cn/#/problem/show/878 设dp[i][j][k]表示在前i个数中,第一个得到的异或值是j,第二个人得到的异或值是k的方案数有多少种. 因为异或后的大小不确定,所以不能压缩数组,但是也不大..可以过. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm>