题意:寻找最大的满足条件的数目
解题思路:
因为要找最大的满足条件的值,不难想到使用DP解决此问题
我们的思路很明晰,首先要设定进行转移的方程布尔类型的f[i][x][y],表示在打完第i只怪兽后剩余x体力和y魔力是否可行
于是转移方程为f[i][x][y]=f[i−1][x+a[i]][y]∣f[i−1][x][y+b[i]]
此方法的时间复杂度为O(n3),显然过不了此题
于是分析一下,不难得出我们使用布尔类型过于浪费空间
重点就在此处, 我们这时会使用一种DP常用的方法, 以实现数组降维
我们会将其中一维的数据转移使数组存储它,此时的f[i][x]就会表示在打完第i只怪兽后体力为x时的剩余魔力最大值
我们的目标就是找到最大的i,使0⩽x⩽n时,f[i][x]⩾0
所以转移方程就变为了f[i][x]=max(f[i][x],f[i−1][x+a[i]]),时间复杂度也降到了O(n2)
AC代码(蒟蒻不会写, 只能转载大犇的了)
Details
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int dp[N][N];
int a[N], b[N];
int n, x, y;
int main() {
cin >> n >> x >> y;
int sum = 0;
int ans = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i] >> b[i];
sum += b[i];
for (int j = 0; j <= x; j++)
dp[i][j] = dp[i - 1][j];
for (int j = a[i]; j <= x; j++)
dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i]] + b[i]);
for (int j = 0; j <= x; j++)
if ((sum - dp[i][j]) <= y)
ans = max(ans, i);
}
cout << ans << endl;
return 0;
}
时间复杂度:O(n2)