2016广东工业大学网络赛 B

Problem B: Sward Art Online

Description

    Krito为了打败第一层的boss - The eye of giant.SAO系统种一个人物可以装备4个物品,分别是左手武器,右手武器,首饰,盔甲,这些都可以增加一定的攻击力。注意每一种装备只能在所属的装备槽,双手武器会同时占用左手武器和右手武器的位置。还有有些首饰和特定的盔甲搭配可以产生不同的加成效果。在现在Krito有很多装备选择,当是他只有一定的金币,他想要获得最高的攻击力,问他应该怎么选择自己的装备才能使攻击力最高.

Input

第1行: 一个数T表示有多少个测试样例(T<=100)

对于每一个测试样例:

第1行:5个数m,a,b,c,d,表示Krito有m个金币,a种头盔,b种首饰,c种武器,d种双手武器(0<=m <=10000,0<=a,b,c,d<=100)

第2至2+a行: 表示可选的头盔,每行两个数,money,atk,表示这个物品的价格,和相应的攻击力加成(0<=money,atk<=100)

第3+a至3+a+b行:表示可选的首饰,每行四个数, money,atk,id,buff . id表示该件首饰如果和编号为id(从0开始)的头盔搭配可以获得buff的攻击力加成(|buff|<=100),id=-1和buff=-1表示没有加成效果

第4+a+b至4+a+b+c行: 表示可选的单手武器,可以装备在单手或者右手槽,注意每种武器只有一个,每行两个数,money,atk,表示这个物品的价格,和相应的攻击力加成(0<=money,atk<=100)

第5+a+b+c至5+a+b+c+d行: 表示可选的双手武器,每行两个数,money,atk,同上。

Output

输出能够获得的最大攻击力。

Sample Input

210 1 1 0 05 55 5 -1 -110 1 1 0 05 55 5 0 10

Sample Output

1020

分析:进行多次01背包问题求解就好了,枚举a[i],b[i],a[i]*b[j]将结果存在一个数组mx中,枚举c[i],d[i],c[i]*c[i-1]/2。将结果存在数组mx2中,最后ans=max(ans,mx[i]+mx2[m-i])。
#include<bits/stdc++.h>
#define MAX 10005
using namespace std;
struct Node
{
	int add,money;
};
struct Node2
{
	int id,add,buff,money;
};

Node A[105],C[105],D[105];
Node2 B[105];
long long mx[MAX],mx2[MAX];
int m,a,b,c,d;
void solve()
{
	for (int i=0;i<a;i++)
	{
		for (int j=m;j>=A[i].money;j--)
		{
			long long t=A[i].add;
			mx[j]=max(mx[j],t);
		}
	}
	for (int i=0;i<b;i++)
	{
		for (int j=m;j>=B[i].money;j--)
		{
			long long t=B[i].add;
			mx[j]=max(mx[j],t);
		}
	}
	for (int x=0;x<a;x++)
	{
		for (int y=0;y<b;y++)
		{
			int mon=A[x].money+B[y].money;
			long long t=A[x].add+B[y].add;
			if (B[y].id==x)
				t+=B[y].buff;
			for (int j=m;j>=mon;j--)
			{
				mx[j]=max(mx[j],t);
			}
		}
	}

	for (int i=0;i<c;i++)
	{
		for (int j=m;j>=C[i].money;j--)
		{
			long long t=C[i].add;
			mx2[j]=max(mx2[j],t);
		}
	}
	for (int i=0;i<d;i++)
	{
		for (int j=m;j>=D[i].money;j--)
		{
			long long t=D[i].add;
			mx2[j]=max(mx2[j],t);
		}
	}
	for (int i=0;i<c;i++)
	{
		for (int j=i+1;j<c;j++)
		{
			int mon=C[i].money+C[j].money;
			long long t=C[i].add+C[j].add;
			for (int x=m;x>=mon;x--)
			{
				mx2[x]=max(mx2[x],t);
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		memset(mx,0,sizeof mx);
		memset(mx2,0,sizeof mx2);
		scanf("%d%d%d%d%d",&m,&a,&b,&c,&d);
		for (int i=0;i<a;i++)
		{
			int atk,mon;
			scanf("%d%d",&mon,&atk);
			A[i].money=mon;
			A[i].add=atk;
		}
		
		for (int i=0;i<b;i++)
		{
			int atk,mon,id,bu;
			scanf("%d%d%d%d",&mon,&atk,&id,&bu);
			B[i].money=mon;
			B[i].add=atk;
			B[i].id=id;
			B[i].buff=bu;
		}
				
		for (int i=0;i<c;i++)
		{
			int atk,mon;
			scanf("%d%d",&mon,&atk);
			C[i].money=mon;
			C[i].add=atk;
		}

		for (int i=0;i<d;i++)
		{
			int atk,mon;
			scanf("%d%d",&mon,&atk);
			D[i].money=mon;
			D[i].add=atk;
		}
		solve();
		long long ans=0;
		for(int i=0;i<=m;i++)
		{
			ans=max(ans,mx[i]+mx2[m-i]);
		}
		printf("%lld\n",ans);
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值