华为机试购物单
动态规划
直接上代码
代码里有注释。
# include <iostream>
# include <vector>
using namespace std;
struct Goods
{
int main_value = 0;
int main_fraction = 0;
int annex1_value = 0;
int annex1_fraction = 0;
int annex2_value = 0;
int annex2_fraction = 0;
};
int main()
{
int N, m;
cin >> N >> m;
// 定义数组来存放商品
N /= 10;
Goods goods[m+1];
for(int i = 1; i <= m; ++i)
{
int v, p, q;
cin >> v >> p >> q;
v /= 10;
if(q == 0)
{
goods[i].main_value = v;
goods[i].main_fraction = v * p;
}
else if(goods[q].annex1_value == 0)
{
goods[q].annex1_value = v;
goods[q].annex1_fraction = v * p;
}
else if(goods[q].annex2_value == 0)
{
goods[q].annex2_value = v;
goods[q].annex2_fraction = v * p;
}
}
// cout << goods[3].annex1_value << endl;
// 动态规划
int dp[32000]; // 每个格子都将存放money所能买到的最大分数
for(int i=0;i<32000;i++)
dp[i] = 0;
// cout << dp[1] << endl;
for(int i = 1; i <= m; ++i)
{
for(int money = N; money >= 1; --money)
{
// 四种情况
// 只买主件
if(money >= goods[i].main_value)
dp[money] = max(dp[money],
dp[money
- goods[i].main_value] // 没买这件商品之前的最大分数
+ goods[i].main_fraction); // 买了这件商品之后获得分数,与原来存放的最大分数比较并更新。
// 主+附1
if(money >= goods[i].main_value + goods[i].annex1_value)
dp[money] = max(dp[money],
dp[money
- goods[i].main_value
- goods[i].annex1_value] // 没买这件商品之前的最大分数
+ goods[i].main_fraction
+ goods[i].annex1_fraction); // 买了这件商品之后获得分数,与原来存放的最大分数比较并更新。
// 主+附2
if(money >= goods[i].main_value + goods[i].annex2_value)
dp[money] = max(dp[money],
dp[money
- goods[i].main_value
- goods[i].annex2_value] // 没买这件商品之前的最大分数
+ goods[i].main_fraction
+ goods[i].annex2_fraction); // 买了这件商品之后获得分数,与原来存放的最大分数比较并更新。
// 主+附1+附2
if(money >= goods[i].main_value + goods[i].annex1_value + goods[i].annex2_value)
dp[money] = max(dp[money],
dp[money
- goods[i].main_value
- goods[i].annex1_value
- goods[i].annex2_value] // 没买这件商品之前的最大分数
+ goods[i].main_fraction
+ goods[i].annex1_fraction
+ goods[i].annex2_fraction); // 买了这件商品之后获得分数,与原来存放的最大分数比较并更新。
// cout << money << ":" << dp[money] << endl;
}
}
cout << dp[N] * 10 << endl;
return 0;
}