洛谷 AT_dp_e Knapsack 2 题解
01 背包,但是背包容量 \(\le10^9\),所以我们不能像模板一样用容量来做状态了。但注意到物品的价值总和 \(\le10^5\)。正难则反,我们考虑用价值来作状态。\(dp_i\) 表示价值达到 \(i\) 所需的最小容量,然后可以像模板那样倒着枚举,\(dp_i=\min(dp_i,dp_{j-w}+v)\)。最后从大到小枚举价值,遇到第一个容量小于等于背包容量的就直接输出。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int N=100100;
int n,w,v,dp[N],mav,maw;
int main()
{
scanf("%d%d",&n,&mav);
maw=n*1000;
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&v,&w);
for(int j=maw;j>=w;j--) dp[j]=min(dp[j],dp[j-w]+v);
}
for(int i=maw;i>=0;i--)
{
if(dp[i]<=mav)
{
printf("%d",i);
return 0;
}
}
return 0;
}

浙公网安备 33010602011771号