队伍配置

队伍配置

https://ac.nowcoder.com/acm/problem/14699

题目描述

萌学姐在玩大型手游《futa go》,他现在准备进入作战环节,所以他准备安排自己的队伍。
队伍配置里,可供玩家选择的作战人物被称作“从者”,玩家可以对每个“从者”可以装备至多1件的“概念礼装”,玩家具有一个cost上限值。详细定义如下:
1、每个从者和概念礼装都具有攻击值ATK。
2、每个从者和概念礼装都会占据一定的cost值。
3、每个从者和概念礼装只能上场一次,不能重复使用。
4、概念礼装只能装备在从者上,不能单独存在。
5、选择的从者和概念礼装的cost值之和不能超过玩家的cost上限值。
6、最多可以选择5名从者(在cost值限制下)。
现在给出玩家仓库的每个从者和每件概念礼装的ATK值和cost值,问在满足定义的条件下,队伍可以凑出的最大ATK值。

输入描述:

第1行输入三个整数n,m,d,代表玩家仓库的从者数量、概念礼装数量和cost上限值。
第2-n+1行,每行输入两个整数a1,b1,表示第i个从者的ATK值和cost值。
第n+2-n+m+1行,每行输入两个整数a2,b2,表示第i个概念礼装的ATK值和cost值。
数据保证:0<n,m≤300,25≤d≤138,1000≤a1≤15488,500≤a2≤2500,3≤b1,b2≤12

输出描述:

输出一行,一个整数,代表可以凑出的最大ATK值。

题解

首先我们可以明确一个问题,就是礼装的内部分配对于最后的结果是不影响的。即礼装装给谁都没有关系,所以这道题我们可以想象成选择最多5个从者和不超过从者的礼装来获得最大的ATK值。
其子问题其实跟01背包是一样的,就是一件物品我们选或者不选,我们设置状态为表示选择个从者和个礼装花费上限为时获得的ATK最大值。
因为从者的个数对于礼装的个数有限制,我们可以先处理从者,即把所有的求出,再去考虑算礼装的情况。
在转移的时候注意一定是容量在个数前转移,写反会出现一个物品被选择多次的情况。

代码

#include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define pii pair<int,int>
#define all(A) A.begin(), A.end()
#define fi first
#define se second
#define MP make_pair
#define rep(i,n) for(register int i=0;i<(n);++i)
#define repi(i,a,b) for(register int i=int(a);i<=(b);++i)
#define repr(i,b,a) for(register int i=int(b);i>=(a);--i)

template<typename T>
inline T read(){
    T s=0,f=1; char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-') f=-1;ch = getchar();}
    while(isdigit(ch)) {s=(s<<3)+(s<<1)+ch-48;ch = getchar();}
    return s*f;
}
#define gn() read<int>()
#define gl() read<ll>()
template<typename T>
inline void print(T x) {
    if(x<0) putchar('-'), x=-x;
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

////////////////////////////////////////////////////////////////////////
int dp[305][305][150];
int tim[105],value[105];
////////////////////////////////////////////////////////////////////////
int main(){
    int n=gn(),m=gn(),d=gn();
    int ans=0;
    for(int i=1;i<=n;++i){
        int a=gn(),b=gn();
        for(int t=d;t>=b;--t){
            for(int k=1;k<=5;++k){
                dp[k][0][t]=max(dp[k][0][t],dp[k-1][0][t-b]+a);
                ans=max(dp[k][0][t],ans);
            }
        }
    }
    for(int i=1;i<=m;++i){
        int a=gn(),b=gn();
        for(int t=d;t>=b;--t){
            for(int k=1;k<=5;++k){
                for(int z=1;z<=k;++z){
                    dp[k][z][t]=max(dp[k][z][t],dp[k][z-1][t-b]+a);
                    ans=max(ans,dp[k][z][t]);
                }
            }   
        }
    }
    print(ans),putchar(10);
}

/**
* In every life we have some trouble
* When you worry you make it double
* Don't worry,be happy.
**/
每日一题 文章被收录于专栏

每日一题题解,在做题过程中不断提升

全部评论

相关推荐

哈哈哈哈哈哈哈哈哈哈这个世界太美好了
凉风落木楚山秋:毕业出路老师不管,你盖个章他好交差就完事了,等你盖完毕业了就不关他事情了
点赞 评论 收藏
分享
Southyeung:我说一下我的看法(有冒犯实属抱歉):(1)简历不太美观,给我一种看都不想看的感觉,感觉字体还是排版问题;(2)numpy就一个基础包,机器学习算法是什么鬼?我感觉你把svm那些写上去都要好一点。(2)课程不要写,没人看,换成获奖经历;(3)项目太少了,至少2-3个,是在不行把网上学习的也写上去。
点赞 评论 收藏
分享
07-04 21:23
已编辑
东莞城市学院 后端
秋招和春招只收到几个中大厂的笔试,本人比较菜,感觉大厂的笔试太难,算法题不能全部做出来就没过了,但是CVTE和小天才的感觉不是很难,基本上都做出来了,笔试还是挂了。Boss上投了Java后端开发都没有回音,boss上有面试机会都是C#工控软件开发方向的,但是这个方向不太懂,资料又少,面试的表现有点差,现在还是想看看Java这边,面试的时候比较有把握点。想请教一下,这份简历还有什么问题,一直没什么机会,还有什么地方要修改的。
程序员小白条:学历太差,民办和公办,外包还得区分的,这个学历+这个简历,没的办法,除非你有人脉,太难了,这环境,何况你都毕业了,连一段实习都没,肯定没公司会挑选了,没竞争力,开发才招几个人,跟你竞争的可不是二本,三本的人哦,何况你在二本,三本里面也排名不高
投递小天才等公司7个岗位
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务