洛谷 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;
}
posted @ 2024-11-01 13:40  MinimumSpanningTree  阅读(11)  评论(0)    收藏  举报