AT_abc364_e [ABC364E] Maximum Glutton [背包]
-
首先第一直觉直接令dp[i][j]表示当前甜度咸度分别为i,j时能吃的最多的菜数进行dp,时间上\(O(nxy)\)肯定是炸的
-
优化方法其实也很简单,我们注意到n相对于x和y来说很小,所以我们只需要想办法把时间复杂度中的x或者y替换成n即可,类似于矩阵乘法时我们选择最小的一个作为平方项复杂度一样,我们让dp[i][j][k]表示前i盘菜吃j盘,甜度为k时的最小咸度,这样只是将所求的量与原本的一个状态量交换,却大大节省了复杂度。
#include<bits/stdc++.h>
using namespace std;
int t;
const int N = 2e5 + 10;
int n,x,y,ans;
struct node {
int a,b;
}in[N];
int dp[90][90][10001];
void solve() {
memset(dp,0x3f,sizeof dp);
cin >> n >> x >> y;
for(int i = 1;i <= n;i++) cin >> in[i].a >> in[i].b;
dp[0][0][0] = 0;
for(int i = 1;i <= n;i++) {
for(int j = 0;j <= i;j++) {
for(int k = 0;k <= x;k++) {
dp[i][j][k] = dp[i - 1][j][k];
if(k - in[i].a >= 0 && j > 0) dp[i][j][k] = min(dp[i][j][k],dp[i - 1][j - 1][k - in[i].a] + in[i].b);
if(dp[i][j][k] <= y) ans = max(ans,j);
}
}
}
if(ans < n) ans++;
cout << ans;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
t = 1;
while(t--) solve();
return 0;
}

浙公网安备 33010602011771号