目录
01背包
01背包:n种不同的物品,每个物品有重量w[i],和价值v[i],每个物品只能拿一次,给你容量为m的背包,怎样才能取得最大价值
普通01背包
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int t,n,m,i,j;
int v[1005],w[1005];
int dp[1005];
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&v[i]);
for(i=0;i<n;i++)
scanf("%d",&w[i]);
for(i=0;i<n;i++)
for(j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]); //表示容量为j时可取得的最大价值
printf("%d\n",dp[m]);
}
return 0;
}
01大背包
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
#define ll long long
ll n,m,dp[maxn],w[maxn],v[maxn];
int main()
{
scanf("%lld%lld",&n,&m);
int sum=0;
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&w[i],&v[i]);
sum+=v[i];//表示所有物品的价值和
}
memset(dp,inf,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++)
for(int j=sum;j>=v[i];j--)
dp[j]=min(dp[j],dp[j-v[i]]+w[i]); //dp[j]表示价值为j的最小容量为dp[j]
for(int i=sum;i>=0;i--)
if(dp[i]<=m) //当容量小于等于背包容量时输出此时的能带走的价值i
{
printf("%d",i);
return 0;
}
}
完全背包
完全背包:n种不同的物品,每个物品有重量w[i],和价值v[i],一个物品可以拿多次,给你容量为m的背包,怎样才能取得最大价值?
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int t,n,m,i,j;
int v[1005],w[1005];
int dp[1005];
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&v[i]);
for(i=0;i<n;i++)
scanf("%d",&w[i]);
for(i=1;i<=n;i++)
for(j=w[i];j<=m;j++) //注意此处与01背包不同,01为倒序
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
printf("%d\n",dp[m]);
}
return 0;
}