题目大意:有n件珠宝,每个珠宝的魅力值为v,重量为w,求在重量不超过m的情况下能达到的最大魅力值。
题目思路:简单的01背包,由于二维数组会超内存所以应该压缩成一维数组。
dp[i][j],表示选取i件物品,重量为j的情况下能达到的最大魅力值,则容易推出dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[j]),可以看出当前的dp[i][j]只和前一轮有关,所以可以采用滚动数组的办法进行压缩:dp[j]=max(dp[j],dp[j-w[i]]+v[i]).
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<stdio.h> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 100005 using namespace std; int v[MAX],w[MAX],dp[MAX]; void Init() { memset(dp,0,sizeof(dp)); memset(w,0,sizeof(dp)); memset(v,0,sizeof(v)); } int main() { int n,m,i,j,a[MAX]; while(scanf("%d%d",&n,&m)!=EOF) { Init();//初始化 for(i=1;i<=n;i++) { scanf("%d%d",&w[i],&v[i]); } dp[0]=0;//确定边界状态 for(i=1;i<=n;i++) { for(j=m;j>=w[i];j--)//倒着进行遍。否则因为前面数据已经发生改变而影响后面的求解。 { dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } } printf("%d ",dp[m]); } return 0; }