您的位置:首页 > 理论基础 > 计算机网络

多说都是泪 GDUT 广东工业大学2016校赛决赛-网络赛 1170 Problem B Sward Art Online

2016-04-10 23:38 435 查看
题目:点我

http://gdutcode.sinaapp.com/problem.php?cid=1031&pid=1

今天打网络个人赛,一开始就不太顺利,到了这个题,刚看到的时候,认为是手到擒拿,结果到最后也没AC。

wa啊T的,最后想尽各种办法优化,结果解法越来越复杂,也离答案越来越远,最后题目认识得都是错的。

有时人喝水也会塞牙缝,到最后一分钟,有人告诉我m最大只有500(其实应该是400)。

我大吃一惊马上加了一句话


结果还是T啊,然后崩溃地离去了。


回来调换了这两句话的位置,就A了(废话咯)

到了大二,感觉很多时候还不如自己大一,去年也是参加广东工业大学的网络赛,相对而言,自己做的情况比现在还好很多。

不知道是不是因为会的东西越来越多,表现还会越来越差。

今天真的应该跟榜的,应该先去做A题的。

感觉什么都不会的时候比赛情况比会了一些东西还好很多。

我总是很偏执,卡在一题上,就死盯着一题,然后就深深地进入了误区。

最近每天睡的也很晚,不知道是不是因为到了高年级就变得喜欢熬夜,该早点休息休息的。

回顾我这一年的acm经历,感觉自己并不能算是能力强的acm选手,或者说离这个标准还差十万八千里。

不过我平时还是有好好训练的,没有说有连续两天都没有做题目的情况,(只有偶尔有个一天没做,因为实在有事或者

想休息休息),感觉暑假集训是个幸福快乐的经历,总的来说现在感觉还是挺好的。

解法:先处理好物品,然后进行分组背包(个人解法,虽说这种解法好像比较麻烦,而且容易错)

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;

#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
typedef long long ll;
typedef pair<int, int> pii;
const int INF =0x3f3f3f3f;
const int maxn= 100 ;
const int maxV= 400 ;

int V;
int a,b,c,d;
struct Helmet_ONE_TWO
{
int cost,val;

} A[maxn+10],C[maxn+10],D[maxn+10];
struct Shoushi
{
int cost,val;
int match,add;

} B[maxn+10];

int VAL[maxV+10];
int dp[maxV+10];

void updatecost(int v,int val)
{
if(v>V) return;
if(VAL[v]<val) VAL[v]=val;
}
void update(int v,int val)
{
if(v>V) return;
if(dp[v]<val) dp[v]=val;
}
void getThing()
{
memset(dp,-1,(V+1)*sizeof dp[0]);
dp[0]=0;
memset(VAL,0,(V+1)*sizeof VAL[0]);
for(int i=1;i<=a;i++)
{
updatecost(A[i].cost,A[i].val);
}
for(int i=1;i<=b;i++)
{
updatecost(B[i].cost,B[i].val);
}

for(int i=1;i<=a;i++)
{
for(int j=1;j<=b;j++)
{
int tcost=A[i].cost+B[j].cost;
int tval=A[i].val+B[j].val;
if(B[j].match==i) tval+=B[j].add;
updatecost(tcost,tval);
}
}

for1(i,c)
{
update(C[i].cost,C[i].val);
}
for1(i,d)
{
update(D[i].cost,D[i].val);
}
for(int i=1;i<=c;i++)
{
for(int j=1;j<i;j++)
{
int tcost=C[i].cost+C[j].cost;
int tval=C[i].val+C[j].val;
update(tcost,tval);
}
}
}

void work()
{

for(int v=V;v>=0;v--)
{
int ret=dp[v];
for(int i=0;i<=V;i++) if(v>=i&& dp[v-i ]!=-1)
{
if(i) dp[v]=max(dp[v],dp[v-i ]+VAL[i]);
else ret=max(ret,dp[v-i ]+VAL[i]);
}
dp[v]=max(dp[v],ret);
}

int ans=0;
for(int v=0;v<=V;v++)
{
ans=max(ans,dp[v]);
}

printf("%d\n",ans);

}
int main()
{
int T;scanf("%d",&T);
while(T--)
{

scanf("%d",&V);
V=min(400,V);
scanf("%d%d%d%d",&a,&b,&c,&d);
for(int i=1;i<=a;i++)
{
scanf("%d%d",&A[i].cost,&A[i].val);
}
for1( i,b)
{
scanf("%d%d%d%d",&B[i].cost,&B[i].val,&B[i].match,&B[i].add);
B[i].match++;
}
for1(i,c)
{
scanf("%d%d",&C[i].cost,&C[i].val);
}
for1(i,d)
{
scanf("%d%d",&D[i].cost,&D[i].val);
}
getThing();
work();

}

return 0;
}



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


HINT

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: