给定n(n<=100)种物品和一个背包。物品i的重量是wi(wi<=100),价值为vi(vi<=100),背包的容量为C(C<=1000)。
应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有两个选择:装入或不装入。不能将物品i装入多次,也不能只装入部分物品i。
输入格式:
共有n+1行输入:
第一行为n值和c值,表示n件物品和背包容量c;
接下来的n行,每行有两个数据,分别表示第i(1≤i≤n)件物品的重量和价值。
输出格式:
输出装入背包中物品的最大总价值。
输入样例:
在这里给出一组输入。例如:
5 10
2 6
2 3
6 5
5 4
4 6
输出样例:
在这里给出相应的输出。例如:
15
基本做法:
时间复杂度O(n*m)
空间的复杂度O(n*m)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mas=1005;
int n,c;
int v[mas],w[mas],f[mas][mas];
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=c;j++)
if(j>=w[i])f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
else f[i][j]=f[i-1][j];
printf("%d",f[n][c]);
return 0;
}
总结:
const int mas=1005,mas=max(n,c)
如果开的过小PTA的答案会报错,我一开始开的105
优化:
实际是对空间进行优化
优化后的时间复杂度O(n*m)
优化后的空间复杂度O(m)//m代表着空间的大小
#include<iostream>
#include<cstdio>
using namespace std;
const int mas=1005;
int n,c;
int w[mas],v[mas],f[mas];
int main()
{
scanf("%d%d",&n,&c);
for(int i=1;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
for(int i=1;i<=n;i++)
for(int j=c;j>=w[i];j--)
if(f[j-w[i]]+v[i]>f[j])f[j]=f[j-w[i]]+v[i];
cout<<f[c];
return 0;
}
总结:
可以进行优化的原因:
1.每次打表的时候只会用到上一行的数值(正上方,以及正上方的前边几个)
2.需要进行注意的是,打表时候要从后往前打表。因为如果从前往后打表,当前行的数值变成当前的数值,但是后边打表需要用的是上一行的表格(被之前的进行覆盖)。
3 进行优化以后一部分的数值进行可以沿用上一行的数值,一定的情况下时间的复杂也进行了优化。