AlenaNuna

导航

HJ16 购物单

题目:https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4?tpId=37&tqId=21239&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37&difficulty=undefined&judgeStatus=undefined&tags=&title=

是个加了限制条件的背包问题。如果q[i]不等于0,那么你就必须买了编号为q[i]的商品才能购买编号为i的商品

注意到一个主件最多只会有两个附件,那就把每个主件带着它的附件合并成一个整体,num_fa是主件数。

对每个整体进行dp,dp[i][j]表示对于前i个整体花费了j元能得到的最大满意度。然后对于每个整体,dp的过程中拆开来维护一下里面的两个附件是否要购买就可以了。

注意到价格只会是10的整数,所以对于价格整体除以10,这样循环的层数可以少10倍,会快一些。输出结果时再把10乘回去就行。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,dp[65][3202],duiying[65],num_fa=0;
 4 struct SP{
 5     int v,p,q,id;
 6 }a[65];
 7 struct Bag{
 8     int v,p,id,num_son;
 9     int sv[3],sp[3],sid[3];
10 }b[65];
11 void init(){
12     cin>>n>>m;
13     n/=10;
14     for(int i=1;i<=m;i++){
15         scanf("%d%d%d",&a[i].v,&a[i].p,&a[i].q);
16         a[i].v/=10;
17         a[i].id=i;
18     }
19     for(int i=1;i<=m;i++){
20         if(a[i].q==0){
21             b[++num_fa].id=a[i].id;
22             b[num_fa].p=a[i].p;
23             b[num_fa].v=a[i].v;
24             for(int j=1;j<=m;j++){
25                 if(a[j].q==b[num_fa].id){
26                     b[num_fa].num_son++;
27                     b[num_fa].sv[b[num_fa].num_son]=a[j].v;
28                     b[num_fa].sp[b[num_fa].num_son]=a[j].p;
29                     b[num_fa].sid[b[num_fa].num_son]=a[j].id;
30                 }
31             }
32         }
33     }
34     return;
35 }
36 void Work(){
37     for(int i=1;i<=num_fa;i++){
38         for(int j=0;j<=n;j++){
39             if(j>=b[i].v){
40                 dp[i][j]=max(dp[i][j],dp[i-1][j-b[i].v]+b[i].v*b[i].p);
41                 for(int k=1;k<=b[i].num_son;k++){
42                     if(j>=b[i].v+b[i].sv[k])
43                         dp[i][j]=max(dp[i][j],dp[i-1][j-b[i].v-b[i].sv[k]]
44                         +b[i].v*b[i].p+b[i].sv[k]*b[i].sp[k]);
45                 }
46                 if(b[i].num_son==2&&j>=b[i].v+b[i].sv[1]+b[i].sv[2])
47                     dp[i][j]=max(dp[i][j],dp[i-1][j-b[i].v-b[i].sv[1]-b[i].sv[2]]
48                         +b[i].v*b[i].p+b[i].sv[1]*b[i].sp[1]+b[i].sv[2]*b[i].sp[2]);
49             }
50             dp[i][j]=max(dp[i][j],dp[i-1][j]);
51         }
52     }
53     return;
54 }
55 void Output(){
56     printf("%d\n",dp[num_fa][n]*10);
57     return;
58 }
59 int main(){
60     init();
61     Work();
62     Output();
63     return 0;
64 }

 

posted on 2024-09-06 20:21  AlenaNuna  阅读(4)  评论(0编辑  收藏  举报