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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章