| 
 | 1 | +Let us consider a monster (D, H) and a unit (d, h).   | 
 | 2 | + | 
 | 3 | +Time taken by monster to kill 1 unit = h/D   | 
 | 4 | +Time taken by unit to kill monster = H/d   | 
 | 5 | + | 
 | 6 | +We need to ensure that the time taken by the monster is strictly more than the time we take to kill the monster   | 
 | 7 | + | 
 | 8 | +h/D > H/d   | 
 | 9 | +h*d > H*D   | 
 | 10 | + | 
 | 11 | +We can treat all the monsters as products (D x H)  | 
 | 12 | + | 
 | 13 | +For a given unit, we need to find the minimum integer c, such that   | 
 | 14 | + | 
 | 15 | +h x (c x d) > H x D   | 
 | 16 | + | 
 | 17 | +-----  | 
 | 18 | + | 
 | 19 | +Another condition is that c <= C/C[i]   | 
 | 20 | + | 
 | 21 | +-----  | 
 | 22 | + | 
 | 23 | +Now, instead of checking the amount of damage a monster can take, let us try to calculate the maximum   | 
 | 24 | +product we can reach with C[i] coins   | 
 | 25 | + | 
 | 26 | +Maximum_product[C[i]] = max(H[i] x D[i]) initially   | 
 | 27 | + | 
 | 28 | +The key insight to propagate this DP is that we can buy multiple sets of the same unit   | 
 | 29 | + | 
 | 30 | +If we buy C coin sets of the i-th unit   | 
 | 31 | + | 
 | 32 | +Maximum_product[C[i] x C] = max(C x H[i] X D[i])   | 
 | 33 | + | 
 | 34 | +-----  | 
 | 35 | + | 
 | 36 | +We can then binary search the answer for each query   | 
 | 37 | + | 
 | 38 | +-----  | 
 | 39 | + | 
 | 40 | +int main()  | 
 | 41 | +{  | 
 | 42 | +    int no_of_elements, max_cost;  | 
 | 43 | +    cin >> no_of_elements >> max_cost;  | 
 | 44 | + | 
 | 45 | +    vector <long long> cost(no_of_elements + 1), damage(no_of_elements + 1), health(no_of_elements + 1);  | 
 | 46 | +    vector <long long> max_product(max_cost + 1, 0);  | 
 | 47 | +    for(int i = 1; i <= no_of_elements; i++)  | 
 | 48 | +    {  | 
 | 49 | +        cin >> cost[i] >> damage[i] >> health[i];  | 
 | 50 | + | 
 | 51 | +        max_product[cost[i]] = max(max_product[cost[i]], damage[i]*health[i]);  | 
 | 52 | +    }  | 
 | 53 | + | 
 | 54 | + | 
 | 55 | +    for(int c = 1; c <= max_cost; c++)  | 
 | 56 | +    {  | 
 | 57 | +        for(int coin_sets = 1; c*1LL*coin_sets <= max_cost; coin_sets++)  | 
 | 58 | +        {  | 
 | 59 | +            max_product[c*coin_sets] = max(max_product[c*coin_sets], max_product[c]*coin_sets);  | 
 | 60 | +        }  | 
 | 61 | +    }  | 
 | 62 | + | 
 | 63 | +    vector <long long> max_product_till(max_cost + 1);  | 
 | 64 | +    for(int i = 1; i <= max_cost; i++)  | 
 | 65 | +    {  | 
 | 66 | +        max_product_till[i] = max(max_product[i], max_product_till[i - 1]);  | 
 | 67 | +    }  | 
 | 68 | + | 
 | 69 | +    int no_of_monsters;  | 
 | 70 | +    cin >> no_of_monsters;  | 
 | 71 | + | 
 | 72 | +    for(int i = 1; i <= no_of_monsters; i++)  | 
 | 73 | +    {  | 
 | 74 | +        long long damage_here, health_here;  | 
 | 75 | +        cin >> damage_here >> health_here;  | 
 | 76 | + | 
 | 77 | +        long long product = damage_here*health_here;  | 
 | 78 | + | 
 | 79 | +        int minimum_coins = upper_bound(all(max_product_till), product) - max_product_till.begin();  | 
 | 80 | + | 
 | 81 | +        cout << (minimum_coins <= max_cost ? minimum_coins : -1) << "\n";  | 
 | 82 | +    }  | 
 | 83 | + | 
 | 84 | +    return 0;  | 
 | 85 | +}  | 
0 commit comments