CF922E Birds 题解

题目传送门

前置知识

背包 DP

解法

观察到 w 极大,若使用正常的背包空间会爆炸。

依据 AT_dp_e Knapsack 2 的经验,考虑将背包“反”着用。设 fi,j 表示到第 i 棵树时一共召唤了 j 只小鸟时剩余的最大魔力值,状态转移方程为 fi,j=min(maxk=0min(j,ci){fi1,jkcosti×k+x},w+b×j),边界为 f0,0=w

最终,有 maxi=0j=1ncj{[fn,i0]×i} 即为所求。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
ll c[10010],sum[10010],cost[10010],f[1010][10010];
int main()
{
    ll n,w,b,x,ans=0,i,j,k;
    cin>>n>>w>>b>>x;
    for(i=1;i<=n;i++)
    {
        cin>>c[i];
        sum[i]=sum[i-1]+c[i];
    }
    for(i=1;i<=n;i++)
    {
        cin>>cost[i];
    }
    memset(f,-0x3f,sizeof(f));
    f[0][0]=w;
    for(i=1;i<=n;i++)
    {
        for(j=0;j<=sum[i];j++)
        {
            for(k=0;k<=min(j,c[i]);k++)
            {
                if(f[i-1][j-k]-cost[i]*k>=0)
                {
                    f[i][j]=max(f[i][j],f[i-1][j-k]-cost[i]*k+x);
                }
            }
            f[i][j]=min(f[i][j],w+b*j);
        }
    }
    for(i=sum[n];i>=0;i--)
    {
        if(f[n][i]>=0)
        {
            ans=i;
            break;
        }
    }
    cout<<ans<<endl;
    return 0;
} 		   		     	
posted @   hzoi_Shadow  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
扩大
缩小
点击右上角即可分享
微信分享提示