题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
#include<stdio.h> #include<string.h> #define max(i,j) ((i>j) ? (i):(j)) int main(){ int N=0,m=0; scanf("%d %d",&N, &m); N /= 10; int price[m+1][4]; //价格 主件 主件+附件1 主件+附件2 主件+附件1+附件2 int pman[m+1][4]; // 满意度 主件 主件+附件1 主件+附件2 主件+附件1+附件2 // 看了一下测试集,主件不一定在附件前,服了 memset(price, 0, sizeof(price)); memset(pman, 0, sizeof(pman)); for(int i = 1; i<= m; i++){ int a=0, b=0, c = 0; scanf("%d %d %d",&a,&b,&c); a /= 10; if(c==0){ //主件 price[i][0] = a; pman[i][0] = a*b; }else if(price[c][1] == 0){ //附件1 price[c][1] = a; pman[c][1] = a*b; }else{ //附件2 附件1+附件2 price[c][2] = a; pman[c][2] = a*b; price[c][3] = price[c][1] + a; pman[c][3] = pman[c][1] + a*b; } } for(int i = 1; i<= m; i++){ for(int k = 1; k <=3;k++){ price[i][k] += price[i][0]; pman[i][k] += pman[i][0]; } } int dp[m+1][N+1]; //用N(j)奖金购买前m(i)个物品的总价值 memset(dp, 0, sizeof(dp)); for(int i = 1; i< m+1;i++){ for (int j = 1; j< N+1; j++){ int max_val = dp[i-1][j]; for(int k = 0; k < 4; k++){ if(price[i][k] == 0){ break; } if(j >= price[i][k]) max_val = max(max_val, dp[i-1][j - price[i][k]] + pman[i][k]); } dp[i][j] = max_val; // printf("%d ,", dp[i][j]); } // printf("\n"); } printf("%d",dp[m][N] * 10); }
把附件和主件看成一体的,对于每个主件,只有四种选择
主件 主件+附件1 主件+附件2 主件+附件1+附件2
然后使用dp迭代使用j元选择前i件 商品的最大满意度dp(i,j)