zoj1013

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


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值