AT_dp_x 题解

题目传送门

题目分析

好水的题,秒了。

看到题面就知道是背包,唯一的问题是怎么优化其复杂度。

如果将 \(x\) 放于 \(y\) 上,那么上面还能堆 \(x_s-y_w\) 的东西,反之则能堆 \(y_s-x_w\) 的东西,所以若有 \(x_s-y_w<y_s-x_w\),则将第 \(x\) 个箱子放在第 \(y\) 个箱子上更优。

排序完再跑背包即可。

贴上代码

#include<bits/stdc++.h>
#define int long long
#define ok printf("1")
#define no printf("0")
using namespace std;
int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-48;
		c=getchar();
	}
	return x*f;
}
const int maxn=2e4+5;
int n;
int ans;
int dp[maxn];
struct node{
	int w,s,v;
}a[maxn];
bool cmp(node x,node y){
	return (x.w+x.s)<(y.w+y.s);
}
inline void init(){
	n=read();
	for(register int i=1;i<=n;++i){
		a[i].w=read();a[i].s=read();a[i].v=read();
	}
	sort(a+1,a+n+1,cmp);
}
signed main(){
	init();
	for(register int i=1;i<=n;++i){
		for(register int j=min(a[i].w+a[i].s,20000LL);j>=a[i].w;--j) dp[j]=max(dp[j],dp[j-a[i].w]+a[i].v);
	}
	for(register int i=1;i<=maxn;++i) ans=max(ans,dp[i]);
	printf("%lld",ans);
}
posted @ 2023-05-19 16:17  yizhixiaoyun  阅读(28)  评论(0)    收藏  举报