题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
#include <stdio.h>
#include <string.h>
#define MAX(a,b) ((a>b)?(a):(b))
// int MAX(int a,int b)
// {
// return a>b?a:b;
// }
int main(void)
{
int N,m; //预算 和 物品个数
scanf("%d %d",&N,&m);
N = N/10;
//穷举所有情况
//四种情况
//1. 主件
//2. 主件+附件1
//3. 主件+附件2
//4. 主件+附件1+附件2
int value[m][4];
int price[m][4];
memset(price,0,sizeof(price));
memset(value,0,sizeof(value));
int v, p, q;
for(int i=0;i<m;i++)
{
scanf("%d %d %d",&v,&p,&q);
v = v/10;
if(!q) //主件
{
price[i][0]=v;
value[i][0]=p * v;
}else
{
if(price[q-1][1]==0)
{
price[q-1][1]=v;
value[q-1][1]=p*v;
}else
{
price[q-1][2]=v;
value[q-1][2]=p*v;
price[q-1][3]=price[q-1][1]+price[q-1][2];
value[q-1][3]=value[q-1][1]+value[q-1][2];
}
}
}
for(int i = 0 ; i < m ; i++)
{
for(int j = 1 ; j < 4 ; j++)
{
price[i][j] += price[i][0];
value[i][j] += value[i][0];
}
}
//得到每种物品的所有选择情况 price[m+1][4] 和对应价值 value[m+1][4]
//其中附件的序号价格价值均为0 因为其不能单独购买
//动态规划数组
int dp[m+1][N+1]; //前i件物品在N+10的预算下的最大价值
memset(dp,0,sizeof(dp));
int maxValue=0;
//至下而上穷举方案 并记录于数组中
for(int i=1;i<m+1;i++) //只有i件物品可供选 只有主件可以买
{
for(int j = 1;j<N+1;j++) //只有j元预算的选择
{
maxValue = dp[i-1][j]; //假设最大价值为当前预算下前i件商品的最大价值
for(int k=0;k<4;k++) //主件需要考虑4种情况
{
if(k>0 && price[i-1][k]==price[i-1][0]) break; //没有附件
if(j>=price[i-1][k]) //预算够了才能买
{
maxValue = MAX(maxValue,dp[i-1][j-price[i-1][k]] + value[i-1][k]);
}
}
dp[i][j]=maxValue;
}
}
printf("%d",dp[m][N]*10);
return 0;
}
查看10道真题和解析