题目:
有n件物品和1个容量为m的背包。第i件物品的费用是w[i],价值是p[i]。求解将哪些物品装入背包可使价值总和最大。
解析:
这道题
是动态规划中最经典的一道题
它承载着许多人的噩梦
也承载着许多人成功后的喜悦
下面我就给大家讲讲
这道题经典的题目
开始
学DP的同志都知道
DP的题目
最重要的是
找到状态转移方程
也就是DP方程
这个后面再说
这道题
我们可以将所有的计算成果
全部放在
二维数组f里面
二维数组的横坐标表示:
如果只有一个物品时、如果只有两个物品时、如果只有三个物品时······一直到只有n个物品时
二维数组的纵坐标表示:
如果重量为1时,如果重量为2时、如果重量为3时······一直到如果重量为m时
所以
我们只要算出f[n][m]
就算出了结果
这道题
的
核心思想是
每一件物品
装还是不装
不装的话
就与上一个相同
所以就是
f[i-1][j]
装的话
就一定要装满
所以就要在前面正好空出一个w[i]的价值
再加上p[i]
所以就是
f[i-1][j-w[i]]+p[i]
但是
有一个注意事项
j要大于等于w[i]
否则不够减的话
就只能选第一个选项
所以这道题的状态转移方程就是:
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+p[i])
下面就是大家最喜欢的代码
代码:
#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int w[1000],p[1000],m,n,a[1000][1000],b[1000][1000];
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>p[i];
memset(a,0,sizeof(a));
for(int j=1;j<=m;j++)
{
for(int i=1;i<=n;i++)
{
if(j>=w[i]) a[i][j]=max(a[i-1][j],a[i-1][j-w[i]]+p[i]);
else a[i][j]=a[i-1][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<a[n][m];
return 0;
}
拜拜!!!