简小胡的背包
描述
给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个
输入
输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
以后n行每行两个数Wi和Vi,表示物品的重量和价值
输出
输出1行,包含一个整数,表示最大价值。
第一种:二维数组的方法;就是用二重循环,一个个填进去;
思路:
dp[k][c]=max(dp[k-1][c],dp[k-1][c-a[k]]+p[k]);
#include<bits/stdc++.h>
using namespace std;
int C,N;
int b[1001][1002];
int a[1001];
int p[1001];
void knapsack()
{
for(int k=1; k<=N; k++)
{
for(int c=1; c<=C; c++)
{
if(a[k]>c)
{
b[k][c]=b[k-1][c];
}
else
{
b[k][c]=max(b[k-1][c],b[k-1][c-a[k]]+p[k]);
}
}
}
}
int main()
{
cin>>N>>C;
memset(b,0,sizeof(b));
a[0]=0;
p[0]=0;
for(int i=1; i<=N; i++)
cin>>a[i]>>p[i];
knapsack();
cout<<b[N][C]<<endl;
return 0;
}
第二种:优化后的背包,用的是一维数组;因为算最大价值问题只与j有关;
思路:
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
#include<bits/stdc++.h>
using namespace std;
int a[1001],b[1001],dp[1001];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--){
if(j<a[i])
break;
else
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
}
}
cout<<dp[m]<<endl;
return 0;
}