Problem - F - Codeforces
黑暗势力的传送门在世界边界打开了,现在整个世界都面临着可怕的威胁。为了关闭传送门并拯救世界,你需要一个接一个地击败n个从传送门中出现的怪物。
只有女巫Vika能够应对这个威胁。她有两个魔法力量——水之魔法和火之魔法。Vika每秒可以生成w单位的水魔法能量和f单位的火魔法能量。她需要能量来施放法术。初始时,Vika没有水魔法和火魔法能量。
从传送门中出现的每个怪物都有自己的力量,用一个正整数表示。为了击败第i个力量为si的怪物,Vika需要施放一个至少具有相同力量的水系或火系法术。换句话说,Vika可以花费至少si单位的水魔法能量来施放水系法术,或者至少si单位的火魔法能量来施放火系法术。
Vika可以立即创建和施放法术。只要她有足够的能量,她可以每秒施放无数次法术。
女巫希望尽快拯救世界,因此告诉她需要多少时间。
输入
每个测试包含多个测试用例。每个测试的第一行包含一个整数t(1≤t≤100),表示测试用例的数量。接下来是每个测试用例的描述。
每个测试用例的第一行包含两个整数w和f(1≤w,f≤109),表示Vika每秒可以生成的水魔法和火魔法能量。
每个测试用例的第二行包含一个整数n(1≤n≤100),表示怪物的数量。
每个测试用例的第三行包含n个整数s1,s2,s3,…,sn(1≤si≤104),表示怪物的力量。
保证所有测试用例中n的总和不超过100。
输出
对于每个测试用例,输出一个整数,表示Vika击败所有怪物所需的最短时间(秒)。
Example
Input
Copy
4
2 3
3
2 6 7
37 58
1
93
190 90
2
23 97
13 4
4
10 10 2 45
Output
Copy
3 2 1 5
题解:
我们可以dp求出在魔法为i时,是否可以全部利用为i的魔法
只有这种情况才能求出最优解,
总共需要的魔法量为sum为怪物生命值的总和
根据数据范围,sum最大为1e6
当i = 0~1e6,并且此时魔法可以完全被利用
会有两种情况,
f利用i,w利用sum - i 两者所用t取最大
同理或者w利用i,f利用sum - i
所有最优情况再取最小即可
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> PII;
const int N = 5e5 + 10;
int a[N];
int dp[N*2];
void solve()
{int n,w,f;cin >> w >> f >> n;int sum = 0;for(int i = 1;i <= n;i++){cin >> a[i];sum += a[i];}memset(dp,0,sizeof dp);dp[0] = 1;for(int i = 1;i <= n;i++){for(int j = 1e6;j >= a[i];j --){dp[j] |= dp[j - a[i]];}}int ans = 1e9;for(int i = 0;i <= 1e6;i++){if(dp[i]){ans = min(ans,max((i + w - 1)/w,(sum - i + f - 1)/f));ans = min(ans,max((i + f - 1)/f,(sum - i + w - 1)/w));}}cout << ans <<"\n";
}
//
signed main()
{int t = 1;ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> t ; while(t--){solve();}
}
//70 30 90
//100 90