背包小记

贴个代码

01背包

倒序枚举

#include <bits/stdc++.h>
using namespace std;
const int M = 1e4+15;
int dp[M];
int main(){
	int m,n;scanf("%d%d",&m,&n);
	for(int i = 1 ; i<=n ; i++){
		int w,v;scanf("%d%d",&w,&v);
		for(int j = m ; j>=w ; j--) dp[j] = max(dp[j],dp[j-w]+v);
	}
	printf("%d",dp[m]);
	return 0;
}

完全背包

#include <bits/stdc++.h>
using namespace std;
const int M = 1e7+15;
long long dp[M];
int main(){
	int m,n;scanf("%d%d",&m,&n);
	for(int i = 1 ; i<=n ; i++){
		int w,v;scanf("%d%d",&w,&v);
		for(int j = w ; j<=m ; j++) dp[j] = max(dp[j],dp[j-w]+v);
	}
	printf("%lld",dp[m]);
	return 0;
}

多重背包二进制拆分

#include <bits/stdc++.h>
using namespace std;
const int M = 2e6+15;
int n,m,v[M],w[M],cnt,dp[M];
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1 ; i<=n ; i++){
		int a,b,c;scanf("%d%d%d",&a,&b,&c);
		for(int j = 1 ; j<=c ; j<<=1) v[++cnt] = a*j,w[cnt] = b*j , c-=j;
		if(c) v[++cnt]=a*c,w[cnt]=b*c;
	}
	for(int i = 1 ; i<=cnt ; i++)
		for(int j = m ; j>=w[i] ; j--)
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
	printf("%d",dp[m]);
	return 0;
}

分组背包

#include <bits/stdc++.h>
using namespace std;
const int N = 1015;
int n,m,w[N][N],v[N][N],c[N],dp[N];
int main(){
	scanf("%d%d",&m,&n);
	for(int i = 1 ; i<=n ; i++){
		int a,b,x;scanf("%d%d%d",&a,&b,&x);
		w[x][++c[x]] = a , v[x][c[x]] = b;
	}
	for(int i = 1 ; i<=n ; i++)
		for(int j = m ; j>=0 ; j--)
			for(int k = 1 ; k<=c[i] ; k++)
				if(j>=w[i][k])
					dp[j] = max(dp[j],dp[j-w[i][k]]+v[i][k]);
	printf("%d",dp[m]);
	return 0;
}
posted @ 2026-06-30 17:38  lrj3247  阅读(5)  评论(0)    收藏  举报