码迷,mamicode.com
首页 > 其他好文 > 详细

2017百度之星资格赛 1003:度度熊与邪恶大魔王

时间:2017-10-14 21:10:47      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:sum   建立   sele   mil   back   数组   return   sam   pre   

Problem:
度度熊为了拯救可爱的公主,于是与邪恶大魔王战斗起来。 邪恶大魔王的麾下有n个怪兽,每个怪兽有a[i]的生命值,以及b[i]的防御力。 度度熊一共拥有m种攻击方式,第i种攻击方式,需要消耗k[i]的晶石,造成p[i]点伤害。 当然,如果度度熊使用第i个技能打在第j个怪兽上面的话,会使得第j个怪兽的生命值减少p[i]-b[j],当然如果伤害小于防御,那么攻击就不会奏效。 如果怪兽的生命值降为0或以下,那么怪兽就会被消灭。 当然每个技能都可以使用无限次。 请问度度熊最少携带多少晶石,就可以消灭所有的怪兽。
Input:
本题包含若干组测试数据。

第一行两个整数n,m,表示有n个怪兽,m种技能。

接下来n行,每行两个整数,a[i],b[i],分别表示怪兽的生命值和防御力。

再接下来m行,每行两个整数k[i]和p[i],分别表示技能的消耗晶石数目和技能的伤害值。

数据范围:

1<=n<=100000

1<=m<=1000

1<=a[i]<=1000

0<=b[i]<=10

0<=k[i]<=100000

0<=p[i]<=1000
Output:
对于每组测试数据,输出最小的晶石消耗数量,如果不能击败所有的怪兽,输出-1

Sample Input
1 2
3 5
7 10
6 8
1 2
3 5
10 7
8 6

Sample Out
6
18
问题如上。
不用完全背包求最小晶石消耗数量:
 1 #define min(a, b) (a) < (b) ? (a) : (b)
 2 
 3 class Solution
 4 {
 5 public:
 6     int dudubear(vector<int> life, vector<int> defense, vector<int> star, vector<int> attack, int n, int m)
 7     {
 8         int rightMinValue = 100000, leftMinValue = 100000, sum = 0;
 9         vector<int> selectValue;
10         vector<int> newselectValue;
11 
12         for (int i = 0; i < n; ++i)
13         {
14             for (int j = 0; j < m; ++j)
15             {
16                 if (attack[j] >= life[i] + defense[i])
17                 {
18                     rightMinValue = min(star[j], rightMinValue);
19                     continue;
20                 }
21                 if ((attack[j] > defense[i]) && (attack[j] < defense[i] + life[i]))
22                 {
23                     selectValue.push_back(j);
24                     continue;
25                 }
26                 if (j == m - 1)
27                 {
28                     return -1;
29                 }
30             }
31             //因为技能可重复使用,但单个技能重复使用累加起来的伤害(攻击-防御)超过怪兽的生命值时无意义
32             //所以每个技能的使用次数不能超过(life[i] / (attack[selectValue[j]] - defense[i]))+1
33             //建立新数组,储存单个技能使用最大次数的数组
34             int count = 0;
35             for (int j = 0; j < selectValue.size(); ++j)
36             {
37                 int items = (life[i] / (attack[selectValue[j]] - defense[i])) + 1;
38                 for (int k = 0; k < items; ++k)
39                 {
40                     newselectValue.push_back(selectValue[j]);
41                     ++count;
42                 }
43             }
44 
45 
46             int flag = 4;
47             int bitcount = 2;
48             for (int j = 3; j <= ((int)pow(2, count)) - 1; ++j)
49             {
50                 if (j == flag)
51                 {
52                     flag = flag << 1;
53                     ++bitcount;
54                     continue;
55                 }
56                 //计算当前情况所耗费晶石数量
57                 int sumDamage = 0, sumStar = 0;
58                 for (int k = 1; k < bitcount + 1; ++k)
59                 {
60                     if ((j >> (k - 1) & 1) == 1)
61                     {
62                         sumDamage += attack[newselectValue[count - k]] - defense[i];
63                         sumStar += star[newselectValue[count - k]];
64                     }
65                 }
66                 if (sumDamage < life[i])
67                     continue;
68                 if (sumStar > rightMinValue)
69                     continue;
70                 leftMinValue = min(sumStar, leftMinValue);
71             }
72             leftMinValue == 100000 ? sum += rightMinValue : sum += leftMinValue;
73             leftMinValue = 100000;
74             rightMinValue = 100000;
75             selectValue.clear();
76             newselectValue.clear();
77         }
78 
79         return sum;
80     }
81 };

 

 
 

2017百度之星资格赛 1003:度度熊与邪恶大魔王

标签:sum   建立   sele   mil   back   数组   return   sam   pre   

原文地址:http://www.cnblogs.com/yeqingqian/p/7668377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!