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;
}
posted @ 2025-05-17 19:49  孤枕  阅读(55)  评论(0)    收藏  举报