真的好难
Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the best charms possible from the N(1 ≤ N≤ 3,402) available charms. Each charm iin the supplied list has a weight Wi(1 ≤ Wi≤ 400), a 'desirability' factor Di(1 ≤ Di≤ 100), and can be used at most once. Bessie can only support a charm bracelet whose weight is no more than M(1 ≤ M≤ 12,880).
Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.
Lines 2..N+1: Line i+1 describes charm i with two space-separated integers: W i and D i
4 6 1 4 2 6 3 12 2 7
23
按照正确的思路写了好长时间,最后一直得不到正确的结果,可能是状态转移方程没有理解清楚,而且还涉及到空间优化的问题(人人为我)
状态转移方程真的不太好理解,方程一直在变根本就找不到它确切的值。这里先贴上别人的AC代码,以后方便查找
学0-1背包前要看的一道题
点击打开链接(神奇的口袋)
关于0-1背包的讲解
空间可以优化
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
static const int N = 3403;
static const int M = 12881;
static int f[N][M]; //表示在前N个物品中取重量不超过M的最佳价值
static int c[N], v[N];
int main()
{
int n, m; //n是物品的数量,m是背包的总容量
while (cin >> n >> m)
{
int i, j;
for (i = 1; i <= n; i++)
{
cin >> c[i] >> v[i]; //c[i]重量 v[i]价值
}
memset(f, 0, sizeof(f));
for (i = 1; i <= n; i++)
{
for (j = 1; j < c[i]; j++) //背包容量小于物体重量 ->不放
f[i][j] = f[i - 1][j]; //价值与上一个状态的价值一样
for(j = c[i]; j <= m; j++)
{
if (f[i - 1][j] < f[i - 1][j - c[i]] + v[i]) //i和j参数的变化控制状态变化
f[i][j] = f[i - 1][j - c[i]] + v[i];
else
f[i][j] = f[i - 1][j];
}
}
cout << f[n][m] << "\n";
}
return 0;
}
空间优化后的代码
#include<iostream>
#include<string.h>
#define M 12881
#define N 3403
using namespace std;
int f[M];
int w[N],v[N];
int main()
{
int n,m;
cin>>n>>m;
for(int k=1; k<=n; k++)
{
cin>>w[k]>>v[k];
}
memset(f, 0, sizeof(f));
for(int i=1; i<=n; i++)
{
for(int j=m; j>=w[i]; j--)
{
if(f[j]<f[j-w[i]]+v[i])
f[j]=f[j-w[i]]+v[i];
}
}
cout<<f[m]<<"\n";
return 0;
}
代码虐我千百遍,我待代码如初恋。