经典DP题目
#include <stdio.h>
#define MAXCARAVAN 100
#define MAXEQUIPMENT 500
#define HELM 0
#define ARMOR 1
#define BOOT 2
struct/* 单装 */
{
int weight, size, capability;
}EQUIPMENT[3];
struct/* 套装 */
{
int num_helm, num_armor, num_boot, capability;
}SET;
struct/* 车 */
{
int weight_limit, size_limit;
}CARAVAN[MAXCARAVAN];
int N, MAX_CAPABILITY;
char BOOT_EACH[MAXCARAVAN][MAXEQUIPMENT][MAXEQUIPMENT];
int PLAN[2][MAXEQUIPMENT][MAXEQUIPMENT], MAX[2][MAXCARAVAN][2];
void GET_MAX()/* 取得每辆车、前 n 辆车能单独放 helm 或 armor 的数量 */
{
int i, j;
for(i=0; i<N; i++)
{
for(j=0; j<2; j++)
{
for(MAX[0][i][j]=0; CARAVAN[i].size_limit >= EQUIPMENT[j].size * MAX[0][i][j] && CARAVAN[i].weight_limit >= EQUIPMENT[j].weight * MAX[0][i][j]; MAX[0][i][j] ++)
;
MAX[1][i][j] = MAX[0][i][j];
}
if(i > 0)
for(j=0; j<2; j++)
MAX[1][i][j] += MAX[1][i-1][j];
}
}
void GET_BOOT_EACH()/* 取得每辆车在存了一定数量 helm 以及 armor 后能存boot的最大数量 */
{
int helm, armor, boot, size_left, weight_left, num;
for(num=0; num<N; num ++)
{
for(helm=0; helm<MAX[0][num][HELM]; helm ++)
{
for(armor=0; armor<MAX[0][num][ARMOR]; armor ++)
{
size_left = CARAVAN[num].size_limit - helm*EQUIPMENT[HELM].size - armor*EQUIPMENT[ARMOR].size;
weight_left = CARAVAN[num].weight_limit - helm*EQUIPMENT[HELM].weight - armor*EQUIPMENT[ARMOR].weight;
if(size_left >= 0 && weight_left >= 0)
{
if(BOOT_EACH[num][helm][armor] == -1)
BOOT_EACH[num][helm][armor] = 0;
while(size_left - EQUIPMENT[BOOT].size >= 0 && weight_left - EQUIPMENT[BOOT].weight >= 0)
{
size_left -= EQUIPMENT[BOOT].size;
weight_left -= EQUIPMENT[BOOT].weight;
BOOT_EACH[num][helm][armor] ++;
}
}
}
}
}
}
void FRESH_PLAN(int index)
{
int num, helm, armor;
num = index % 2;
for(helm=0; helm<MAXEQUIPMENT; helm ++)
{
for(armor=0; armor<MAXEQUIPMENT; armor ++)
{
PLAN[num][helm][armor] = -1;
}
}
}
void GET_PLAN(int num, int index)/* 取得前 n 辆车在放了一定量 helm 和 armor 后能放 boot 的最大数量 */
{
int helm, armor, boot, helm_pre, armor_pre;
if(num == 0)
{
FRESH_PLAN(index);
for(helm=0; helm<MAX[0][num][HELM]; helm ++)
for(armor=0; armor<MAX[0][num][ARMOR]; armor ++)
if(BOOT_EACH[num][helm][armor] >= 0)
PLAN[index%2][helm][armor] = BOOT_EACH[num][helm][armor];
return;
}
GET_PLAN(num-1, index+1);
FRESH_PLAN(index);
for(helm=0; helm<MAX[0][num][HELM]; helm ++)/* 遍历从 0~MAX[0][num][]+MAX[1][num-1][] 的所有可能 */
{
for(armor=0; armor<MAX[0][num][ARMOR]; armor ++)
{
for(helm_pre=0; helm_pre<MAX[1][num-1][HELM]; helm_pre ++)
{
for(armor_pre=0; armor_pre<MAX[1][num-1][ARMOR]; armor_pre ++)
{
/* 看是否有效 */
if(BOOT_EACH[num][helm][armor] >= 0 && PLAN[(index+1)%2][helm_pre][armor_pre] >= 0)
{
boot = PLAN[(index+1)%2][helm_pre][armor_pre] + BOOT_EACH[num][helm][armor];
if(PLAN[index%2][helm+helm_pre][armor+armor_pre] < boot)
{
PLAN[index%2][helm+helm_pre][armor+armor_pre] = boot;
}
}
}
}
}
}
}
int GET_CAPABILITY(int helm, int armor, int boot)/* 计算防御力 */
{
int set_count = 0;
while(helm-SET.num_helm >= 0 && armor-SET.num_armor >= 0 && boot-SET.num_boot >= 0)
{
set_count ++;
helm -= SET.num_helm;
armor -= SET.num_armor;
boot -= SET.num_boot;
}
return helm*EQUIPMENT[HELM].capability + armor*EQUIPMENT[ARMOR].capability + boot*EQUIPMENT[BOOT].capability + set_count*SET.capability;
}
void CALCULATE()/* 总调用 */
{
int num, helm, armor, cur_capability;
for(num=0; num<N; num ++)/* 初始化 */
{
for(helm=0; helm<MAXEQUIPMENT; helm ++)
{
for(armor=0; armor<MAXEQUIPMENT; armor ++)
{
BOOT_EACH[num][helm][armor] = -1;
}
}
}
GET_MAX();
GET_BOOT_EACH();
GET_PLAN(N-1, 0);
MAX_CAPABILITY = 0;
for(helm=0; helm<MAX[1][N-1][HELM]; helm ++)
{
for(armor=0; armor<MAX[1][N-1][ARMOR]; armor ++)
{
if(PLAN[0][helm][armor] >= 0)
{
cur_capability = GET_CAPABILITY(helm, armor, PLAN[0][helm][armor]);
if(cur_capability > MAX_CAPABILITY)
{
MAX_CAPABILITY = cur_capability;
}
}
}
}
}
int main()
{
int i, count = 0;
while(scanf("%d", &N) && N != 0)
{
count ++;
if(count > 1) putchar(10);
for(i=0; i<3; i++)
scanf("%d%d%d", &EQUIPMENT[i].weight, &EQUIPMENT[i].size, &EQUIPMENT[i].capability);
scanf("%d%d%d%d", &SET.num_helm, &SET.num_armor, &SET.num_boot, &SET.capability);
for(i=0; i<N; i++)
scanf("%d%d", &CARAVAN[i].weight_limit, &CARAVAN[i].size_limit);
CALCULATE();
printf("Case %d: %d\n", count, MAX_CAPABILITY);
}
return 0;
}