算法-动态规划之购物单


 分析和思路:把附件1和附件2输入后,然后用“只买主件“、“ 只买主件+附件1“ ,“ 只买主件+附件2“、  “ 买主件+附件1+附件2“ ,实际归为了新的产品种类。然后建立状态转移方程即可。详细代码如下:

//在状态转移时如何判断这个主件有几个附件?答案是不需要判断,直接用  if(j>=zj[i]) if(j>=zj[i]+ fj1[i])这样的语句自动归类到不同的种类了。注意,在接收附件1和附件2的参数是也是有技巧的。

 

 1 #include "iostream"
 2 using namespace std;
 3 int main()
 4 {
 5    int N=0;
 6    int m=0;
 7    int dp[32000];
 8    int zj[60],fj1[60],fj1_p[60],v[60],p[60];
 9    int q[60]={0};
10 
11    int fj2[60]={0};
12    int fj2_p[60];
13    while(cin>>N>>m)
14    {
15        int temp=m;
16        int i=1;
17        while(temp--)
18        {
19            cin>>v[i];
20            cin>>p[i];
21            int q_temp=0;
22            cin>>q_temp;
23            if(q_temp==0)
24            {
25                zj[i]=v[i];
26            }
27            else if(fj1[q_temp]==0)
28            {
29                fj1[q_temp]=v[i];
30                fj1_p[q_temp]=p[i];
31            }
32            else 
33            {
34                fj2[q_temp]=v[i];
35                   fj2_p[q_temp]=p[i];
36            }
37            i++;
38        }
39    
40 
41    for(int i=1;i<=m;i++)
42    {
43        for(int j=N;j>=0;j--)
44        {
45 
46            //只买主件
47            if(j>=zj[i])
48            {
49 
50                dp[j]=max(dp[j],dp[j-zj[i]]+zj[i]*p[i]);
51            }
52            //买主件+附件1
53            if(j>=zj[i]+  fj1[i])
54            {
55 
56                dp[j]=max(dp[j],dp[j-zj[i]-fj1[i]]+zj[i]*p[i]+fj1_p[i]*fj1[i]);
57            }
58 
59            //买主件+附件2
60            if(j>=zj[i]+fj2[i])
61            {
62 
63                dp[j]=max(dp[j],dp[j-zj[i]-fj2[i]]+zj[i]*p[i]+fj2_p[i]*fj2[i]);
64            }
65 
66            //买主件+附件1+附件2
67            if(j>=zj[i]+fj1[i]+fj2[i])
68            {
69 
70                 dp[j]=max(dp[j],dp[j-zj[i]-fj1[i]-fj2[i]]+zj[i]*p[i]+fj1_p[i]*fj1[i]+fj2_p[i]*fj2[i]);
71            }
72        }
73 
74       }
75    }
76    cout<<dp[N];
77     return 0;
78 }