題面:Ann正在打體力為H的怪獸,Ann有n種咒語,第i種咒語可以造成A[i]點傷害,但需要花費B[i]點魔法,咒語使用次數不限,當怪獸體力小於等於0時死亡。求殺死怪獸需要的最少魔法。
範圍:1<=H<=1E4; 1<=n<=1E3; 1<=A[i],B[i]<=1E4
思路:完全揹包的變形,記dp[i][j]表示僅使用前i種咒語、造成j點傷害所需要的最少魔法,按選與不選轉移。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
const int N = 1005;
const int M = 10005;
const int inf = 1E16;
int H, n, A[N], B[N], dp[M];
void solve() {
cin >> H >> n;
rep(i,1,n) cin >> A[i] >> B[i];
rep(i,1,H) dp[i] = inf;
dp[0] = 0;
rep(i,1,n) rep(j,0,H) {
if (j < A[i])
dp[j] = min(dp[j], B[i]);
else
dp[j] = min(dp[j], dp[j-A[i]]+B[i]);
}
cout << dp[H] << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}