01背包条件
是在n件物品取出若干件放在大小(空间)为w的背包里!
详细说就是有n件物品,一个容量为w的背包,第i件物品重量为w1[i],价值c[i],求哪些物品装入背包可以让价值和最大。
01背包的特点
每种物品仅有一件!!!可以选择放或不放。
状态转移方程
普通的方程式
dp[i][w]=max{dp[i-1][c],dp[i-1][c-w1[i]]+c[i]}
滚动方程式
dp[j]=max(c[i]+dp[j-w[i]],dp[j]);
举个栗子
有4个物品,背包的容量为20
求:背包最多能放下多少价值的物品
输入样例
第1行分别输入n(物品数量)与w(容量)
第2到n+1行分别输入w1(重量)与c(价值)
4 20
2 4
4 1
10 17
3 5
输出样例
27
代码-二维
#include <bits/stdc++.h>
using namespace std;
int w[210],c[210],dp[210][210];
int sum;
int main(){
int m,n;
cin>>m>>n;
for(int i=1;i<=m;i++)
{
cin>>w[i]>>c[i];
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(j>=w[i])
{
dp[i][j]=max(c[i]+dp[i-1][j-w[i]],dp[i-1][j]);
}
else
{
dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[m][n];
return 0;
}
代码-一维
#include <bits/stdc++.h>
using namespace std;
int w[210],c[210],dp[210];
int main(){
int m,n;
cin>>m>>n;
for(int i=1;i<=m;i++)
{
cin>>w[i]>>c[i];
}
for(int i=1;i<=m;i++)
{
for(int j=n;j>=w[i];j--)
{
dp[j]=max(c[i]+dp[j-w[i]],dp[j]);
}
}
cout<<dp[n];
return 0;
}
啦啦啦
01背包题目练习
还有 开心的金明,采药(NOIP2005普及组第三题)等题都可以用01背包做
01背包问题(旅行者的背包)
描述
一个旅行者有一个最多能装 M 公斤的背包,现在有 n 件物品,它们的重量分别是W1,W2,…,Wn,它们的价值分别为C1,C2,…,Cn,求旅行者能获得最大总价值。
格式
输入格式
第一行:两个整数,M(背包容量,M≤200)和N(物品数量,N≤30); 第2…N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
输出格式
仅一行,一个数,表示最大总价值。
样例
输入样例
10 4
2 1
3 3
4 5
7 9
输出样例
12
代码
#include <bits/stdc++.h>
using namespace std;
int w[210],c[210],dp[210][210];
int sum;
int main(){
int m,n;
cin>>m>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>c[i];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(j>=w[i])
{
dp[i][j]=max(c[i]+dp[i-1][j-w[i]],dp[i-1][j]);
}
else
{
dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[n][m];
return 0;
}
Ps:一维滚动方程式是无法求出装了什么物品进去的,二维的可以
完结撒花~