最强兵力 | ||||||
| ||||||
Description | ||||||
《魔兽争霸》,经典的即时策略游戏。在游戏里,要建造或者生产一个攻击单位,需要消耗金钱和木材,并且还占据一定的食物数量,有些攻击单位还需要建造其他建筑才能进行生产。 为了简化问题,我们修改一下,假设有三种能建造攻击单位的建筑,分别为A B C,其中,B只能在A建造之后才能建造,C只能在B建造之后才能建造,建造它们所需的金钱和木材分别为Ag Aw, Bg Bw, Cg Cw,Ag为建造A所需的金钱,Aw为建造A所需的木材,依次类推。 这三种建筑生产不同的攻击单位,每个生产一个攻击单位,需要消耗金钱g,木材w,我们忽略食物的占据,每个单位有各自的攻击力,生产的攻击单位越多,单个攻击单位的攻击力越强,总体的攻击力就越强,总体的攻击力为所有攻击单位攻击力之和,现在假设每种攻击单位生产数量没有上限。 你现在只有金钱G和木头W,有N种攻击单位,它们分别产自不同的建筑。 如何安排这些资源,才能使得总的攻击力最强。 | ||||||
Input | ||||||
有多组测试数据,对于每组测试数据,第一行为6个整数Ag, Aw, Bg, Bw, Cg, Cw,为建造三种建筑的各自所需的金钱和木材花费,第二行为三个整数G W N,接下来有N行,每一行表示一种攻击单位的信息,包含四个整数gi, wi, ai, di,gi为金钱花费wi为木材花费,ai为攻击力大小,di表示这个攻击单位从哪个建筑生产。 数据范围:0<=Ag,Aw,Bg,Bw, Cg,Cw<=100 1<=G<=1000, 1<=W<=100, N<=100,1<=gi,wi,ai<=100,di为大写字母A、B或C。 处理到文件结束,测试数据不超过5组。 | ||||||
Output | ||||||
对于每组测试数据,输出一行,包含一个整数,为最强的攻击力。
| ||||||
Sample Input | ||||||
1 1 2 20 30 30 100 100 6 2 1 10 A 2 2 15 A 3 4 20 B 5 4 30 B 6 9 60 C 15 7 220 C | ||||||
Sample Output | ||||||
940 | ||||||
Source | ||||||
计算机科学与技术学院2012级新生程序设计竞赛(正式赛) | ||||||
Author | ||||||
黄李龙@HRBUST |
思路:
1、很明显的完全背包的模型。只不过其变化为费用从一维变化到二维。
那么我们可以设定dp【i】【j】【k】表示当前处理到第i种物品,其金钱容量为j,木材容量为k的最大攻击力。
根据完全背包空间优化,我们设定dp【j】【k】表示其金钱容量为j,木材容量为k的最大攻击力。
其状态转移方程:
dp【j】【k】=max(dp【j】【k】,dp【j-a【i】.g】【k-a【i】.w】+a【i】.ai);
2、因为只有三种建筑,而且必须按照A.B.C的顺序来建立。
那么我们直接分类讨论即可:
①只建立A的情况
②建立了A和B的情况
③全部都建立了的情况
那么我们此时跑三次二维费用完全背包。维护最大值即可、
Ac代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
struct node
{
int g,w,ai;
char s[5];
}a[1515];
int dp[1020][120];
int main()
{
int ag,aw,bg,bw,cg,cw;
while(~scanf("%d%d%d%d%d%d",&ag,&aw,&bg,&bw,&cg,&cw))
{
int g,w,n;
scanf("%d%d%d",&g,&w,&n);
for(int i=0;i<n;i++)
{
scanf("%d%d%d%s",&a[i].g,&a[i].w,&a[i].ai,a[i].s);
}
int output=0;
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
if(a[i].s[0]!='A')continue;
for(int j=a[i].g;j<g;j++)
{
for(int k=a[i].w;k<w;k++)
{
dp[j][k]=max(dp[j][k],dp[j-a[i].g][k-a[i].w]+a[i].ai);
}
}
}
if(g>ag&&w>aw)output=max(output,dp[g-ag][w-aw]);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
if(a[i].s[0]=='C')continue;
for(int j=a[i].g;j<g;j++)
{
for(int k=a[i].w;k<w;k++)
{
dp[j][k]=max(dp[j][k],dp[j-a[i].g][k-a[i].w]+a[i].ai);
}
}
}
if(g>ag+bg&&w>aw+bw)output=max(output,dp[g-ag-bg][w-aw-bw]);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
for(int j=a[i].g;j<g;j++)
{
for(int k=a[i].w;k<w;k++)
{
dp[j][k]=max(dp[j][k],dp[j-a[i].g][k-a[i].w]+a[i].ai);
}
}
}
if(g>ag+bg+cg&&w>aw+bw+cw)output=max(output,dp[g-ag-bg-cg][w-aw-bw-cw]);
printf("%d\n",output);
}
}