题解 | #购物单#
购物单
http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
题解:
如果没有附件,单纯只有主件的话,就转化成0-1背包的问题;
当有附件的时候,但是附件至多有两件,所以就分成如下
1、选或者不选主件;
2、选主件+ 附件A
3、选主件+ 附件B
4、选主件+ 附件A+附件B
其中用price[] 数组来存 v[i],但是由于每个主件选的情况分多种,所以改成用二位数组来存。其中第二维表示可能选取的情况;
再用pxw[][]表示price*weight存重要性,即0-1背包里面的 w[i];
所以就有0-1背包问题dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
转化成dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i][k]]+w[i][k]); 其中 k = 0,1,2,3 表示选取主件的情况;
如果没有附件,单纯只有主件的话,就转化成0-1背包的问题;
当有附件的时候,但是附件至多有两件,所以就分成如下
1、选或者不选主件;
2、选主件+ 附件A
3、选主件+ 附件B
4、选主件+ 附件A+附件B
其中用price[] 数组来存 v[i],但是由于每个主件选的情况分多种,所以改成用二位数组来存。其中第二维表示可能选取的情况;
再用pxw[][]表示price*weight存重要性,即0-1背包里面的 w[i];
所以就有0-1背包问题dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
转化成dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i][k]]+w[i][k]); 其中 k = 0,1,2,3 表示选取主件的情况;
/* 题解:
如果没有附件,单纯只有主件的话,就转化成0-1背包的问题;
当有附件的时候,但是附件至多有两件,所以就分成如下
1、只选主件;
2、选主件+ 附件A
3、选主件+ 附件B
4、选主件+ 附件A+附件B
其中用price[] 数组来存 v[i],但是由于每个主件选的情况分多种,所以改成用二位数组来存。其中第二维表示可能选取的情况;
再用pxw[][]表示price*weight存重要性,即0-1背包里面的 w[i];
所以就有0-1背包问题dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
转化成dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i][k]]+w[i][k]); 其中 k = 0,1,2,3 表示选取主件的情况;
*/
#include"iostream"
#include"vector"
using namespace std;
const int MAX = 66;
int main()
{
int n , m ;
cin>>n>>m ;
vector<vector<int>> v(MAX,vector<int>(3,0));
vector<vector<int>> w(MAX,vector<int>(3,0));
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
int a, b , c , d , e , f ;
for(int i = 1; i <= m ; i++)
{
cin>>a>>b>>c;
b *= a;
if(c == 0)
v[i][c] = a, w[i][c] = b;
else{
if(v[c][1] == 0)
v[c][1] = a, w[c][1] = b;
else
v[c][2] = a, w[c][2] = b;
}
}
for(int i = 1 ; i <= m ; i++)
{
for(int j = 0; j <= n ; j++)
{
a = v[i][0], b = w[i][0];
c = v[i][1], d = w[i][1];
e = v[i][2], f = w[i][2];
dp[i][j] = j >= a ? max(dp[i-1][j-a]+b,dp[i-1][j]):dp[i-1][j];
dp[i][j] = j >= a + c ? max(dp[i-1][j-a-c]+b+d,dp[i][j]):dp[i][j];
dp[i][j] = j >= a + e ? max(dp[i-1][j-a-e]+b+f,dp[i][j]):dp[i][j];
dp[i][j] = j >= a + c + e ? max(dp[i-1][j-a-c-e]+b+d+f,dp[i][j]):dp[i][j];
}
}
cout<<dp[m][n]<<endl;
return 0;
}
/*
#include"iostream"
#include"vector"
#include"map"
#include"algorithm"
#include"string"
#include"cstring"
#include"cmath"
#include"queue"
#include"stack"
using namespace std;
int main()
{
int n , m ;
cin>>n>>m;
vector<vector<int>> price(61,vector<int>(3,0));
vector<vector<int>> pxw(61,vector<int>(3,0)); // 价格乘重要性
vector<vector<int>> dp(m+1,vector<int>(n+1,0)); // m见物品,总价值为n;
int val, p, zof, w;
for(int i = 1; i <= m ; i++)
{
cin>>val>>p>>zof;
w = p*val;
if(zof == 0) // 说明是主件
{
price[i][0] = val;
pxw[i][0] = w;
}
else{ // 当为附件时;
if(price[zof][1] == 0)
{
price[zof][1] = val;
pxw[zof][1] = w;
}
else if(price[zof][2] == 0)
{
price[zof][2] = val;
pxw[zof][2] = w;
}
}
}
// 分组背包问题;0-1背包的升级版,完全背包;
for(int i = 1; i <= m ;i++)
{
for(int j = 0 ; j <= n; j++)
{
int a = price[i][0], b = pxw[i][0];
int c = price[i][1], d = pxw[i][1];
int e = price[i][2], f = pxw[i][2];
dp[i][j] = j >= a ? max(dp[i-1][j],dp[i-1][j-a]+b): dp[i-1][j];
dp[i][j] = j>= a+c ? max(dp[i][j],dp[i-1][j-a-c]+b+d) : dp[i][j];
dp[i][j] = j>= a+e ? max(dp[i][j],dp[i-1][j-a-e]+b+f) : dp[i][j];
dp[i][j] = j>= a+c+e ? max(dp[i][j],dp[i-1][j-a-c-e]+b+d+f) : dp[i][j];
}
}
cout<<dp[m][n]<<endl;
return 0;
}
*/
小天才公司福利 1222人发布
