题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
#include <stdio.h> #define MAX(a,b) ((a)>(b))?(a):(b) typedef unsigned int uint32_t; void GetInput(void); uint32_t SolveShopProb(int N, int m); //结果定义为uint32_t, 因为int类型最大为65535,可能溢出。 int main() { GetInput(); return 0; } int V[61][3] = {0}; int VP[61][3] = {0}; //获取数据 void GetInput(void) { int N = 0; int m = 0; int v = 0;//输入缓存变量v、p、q int p = 0; int q = 0; scanf("%d %d", &N, &m); for (int i = 1; i <= m; i++) { scanf("%d", &v); scanf("%d", &p); scanf("%d", &q); //输入合法性检查 if(v%10 != 0) perror("Input Error!"); if(p<1 || p>5) perror("Input Error!"); if(q<0 || q>m) perror("Input Error!"); //输入数据规范化处理。(将附件设置在主件价格、重要度数组成员中) if (q == 0) { V[i][0] = v / 10; VP[i][0] = v * p; } else { if (V[q][1] != 0) { V[q][2] = v / 10; VP[q][2] = v * p; } else { V[q][1] = v / 10; VP[q][1] = v * p; } } } long res = SolveShopProb(N, m); printf("%ld", res); } //运算部分 uint32_t SolveShopProb(int N, int m) { //uint32_t DP[3200]; //32000/10 = 3200,要初始化为0,否则里面一开始是很大的值。 uint32_t DP[3200] ={0}; //for (int i = 1; i <= m && V[i][0] != 0; i++) //跳过附件应该用 if--continue,不能在这里写&& V[i][0] != 0,因为这样会中断整个for循环, for (int i = 1; i <= m; i++) { if(V[i][0] == 0) continue;//跳过附件 for (int j = N / 10; j >= V[i][0]; j--) { //第零种情况:无法装下:DP[i]=DP[i] //第一种情况:只有主件 uint32_t temp_max = DP[j - V[i][0]] + VP[i][0]; DP[j] = MAX(DP[j], temp_max); //第二种情况:主件+附件1 if (V[i][1] != 0) //如果有附件1 { int vsum = V[i][0] + V[i][1]; if (j >= vsum) { temp_max = DP[j - vsum] + VP[i][0] + VP[i][1]; } DP[j] = MAX(DP[j], temp_max); if (V[i][2] != 0) //如果有附件2 { //第三种情况:主件+附件2 vsum = V[i][0] + V[i][2]; if (j >= vsum) { temp_max = DP[j - vsum] + VP[i][0] + VP[i][2]; } DP[j] = MAX(DP[j], temp_max); //第四种情况:主件+附件1+附件2 vsum = V[i][0] +V[i][1]+V[i][2]; if (j >= vsum) { temp_max = DP[j - vsum] + VP[i][0] + VP[i][1]+ VP[i][2]; } DP[j] = MAX(DP[j], temp_max); } } } // printf("when i=%d, DP[N/10]=%d\n", i,DP[N/10]); } return DP[N/10]; }