题解 | #购物单#超清楚的分析
购物单
http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
我本身不是科班出身,通过查阅资料,理解了最简单的01背包问题,下面谈一谈我的理解
背包问题主要就是这个等式 dp[n][c]=max{dp[n-1][c-cost[i]]+value[i],dp[n-1][c]}
他是一个状态转移方程,n指的是背包问题里放物品的个数,该物品有重量(代价)和价钱(价值)两个属性,c指的是背包能背的重量,而dp[n][c]指的是在前n个物品中装到承载重量为c的背包中,使得背包里的物品总价值最大。我们可以仔细思考一下,发现这个最大值的状态跟他把前n-1个物品装到承载为c的背包中似乎有关系。这个等式我认为应该这样理解,max里的第一项代表背包里装了第i个物品,第二项代表没装。意思就是前n项能得出来的最大值,要么装了i物品得到的(第一项我们把i物品扣掉得到的式子dp[n-1][c-cost[i]就是前n-1个物品在该承重下的最大值,然后再加上value[i]得到可能的现有状态的最大值),要么没装就可以得到,那其实就是只有n-1项也可以得到n项状态的最大值。
首先要明白背包问题,背包是作为一种条件限制,可以理解为背包就是“某种有限的东西”,举个例子,比如这道题“有限的东西”就是指的“他的年终奖”,而背包问题里物品的“重量”,抽象的说就是某种“代价”,这道题的“代价”就是每件物品的价钱,而背包问题里的物品的“价值”,可以抽象成”某种有用的属性“,这道题的“某种有用的属性”就是题干说的重要程度
下面程序的cost就是指的代价,value指的价值,而题目中的主件与附件,我们可以把它想象成捆绑在一起,也就是无论它是哪种情况(1、主件;2、主件,附件1;3、主件,附件2;4、主件,附件1,附件2)我们都先把它想象成一个整体。
#include <string>
#include <set>
#include <vector>
using namespace std;
int main() {
unsigned N, m;
unsigned cost,value , inherit;
cin >> N >> m;
//N/=10;
vector<vector<unsigned>> dp(m + 1, vector<unsigned>(N + 1, 0));
vector<vector<unsigned>> costarray(m + 1, vector<unsigned>(4, 0));
vector<vector<unsigned>> valuearray(m + 1, vector<unsigned>(4,0));
for (int i = 1; i <= m; i++) {
cin >> cost >> value >> inherit;
//cost /= 10;
if (inherit == 0) {
valuearray[i][1] = value;
costarray[i][1] = cost;
}
else if (inherit != 0 && costarray[inherit][2] == 0) {
valuearray[inherit][2] = value;
costarray[inherit][2] = cost;
}
else {
valuearray[inherit][3] = value;
costarray[inherit][3] = cost;
}
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= N; j++) {
unsigned valueprimer = valuearray[i][1];
unsigned costprimer = costarray[i][1];
unsigned valueherit1 = valuearray[i][2];
unsigned costherit1 = costarray[i][2];
unsigned valueherit2 = valuearray[i][3];
unsigned costherit2 = costarray[i][3];
unsigned x1 = costprimer;
unsigned x2 = costprimer+costherit1;
unsigned x3 = costprimer+costherit2;
unsigned x4 = costprimer+costherit1+costherit2;
unsigned m1 = valueprimer * costprimer;
unsigned m2 = valueprimer * costprimer + valueherit1 * costherit1;
unsigned m3 = valueprimer * costprimer + valueherit2 * costherit2;
unsigned m4 = valueprimer * costprimer + valueherit1 * costherit1 + valueherit2 * costherit2;
unsigned prev1 = dp[i - 1][j];
dp[i][j] = j >= x1 ? max(prev1, dp[i - 1][j - x1] + m1) : prev1;
dp[i][j] = j >= x2 ? max(dp[i][j], dp[i - 1][j - x2] + m2) : dp[i][j];
dp[i][j] = j >= x3 ? max(dp[i][j], dp[i - 1][j - x3] + m3) : dp[i][j];
dp[i][j] = j >= x4 ? max(dp[i][j], dp[i - 1][j - x4] + m4) : dp[i][j];
}
}
cout << dp[m][N] << endl;
}