购物单

 

王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

 

主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅

 

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
    设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
    请你帮助王强设计一个满足要求的购物单。

 

 

知识点 字符串
运行时间限制 0M
内存限制 0
输入

输入的第 1 行,为两个正整数,用一个空格隔开:N m

(其中 N ( <32000 )表示总钱数, m ( <60 )为希望购买物品的个数。)

 

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q

 

(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)

 

 

输出
 输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值( <200000 )。

 

 

样例输入 1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0
样例输出 2200

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#include<iostream>
using namespace std;
 
int max(int a, int b)
{
    return a>b?a:b;
}
 
int main()
{
    int N,m;
    cin>>N;
    cin>>m;
 
    int *arrv;
    int *arrw;
    int *arridx;
    int **arrsub;
    int *arrsubNum;
 
    arrv = new int [m+1];
    arrw = new int [m+1];
    arridx = new int [m+1];
 
    arrsub = new int* [m+1];
    for(int i=0; i<m+1; i++)
    {
        arrsub[i] = new int [2];
    }
    arrsubNum = new int [m+1];
 
 
    int minv = 100000;
    for(int i=1; i<=m; i++)
    {
        int tmpv, tmpw, tmpidx;
        cin>>tmpv>>tmpw>>tmpidx;
 
        if(tmpidx==0 && tmpv < minv)
        {
            minv = tmpv;
        }
 
        arrv[i] = tmpv/10;
        arrw[i] = tmpw;
        arridx[i] = tmpidx;
    }
    minv = minv/10;
 
 
    for(int i=1; i<=m; i++)
    {
        arrsubNum[i] = 0;
    }
 
    for(int i=1; i<=m; i++)
    {
        if(arridx[i]!=0)
        {
            int idx = arridx[i];
            arrsub[idx][ arrsubNum[idx] ] = i;
            arrsubNum[idx]++;
        }
    }
/*
    cout<<"ok imput"<<endl;
    for(int i=1; i<=m; i++)
    {
        cout<<arrv[i]<<' '<<arrw[i]<<' '<<arridx[i]<<' '<<arrsubNum[i]<<endl;
        cout<<arrsub[i][0]<<' '<<arrsub[i][1]<<endl;
    }
    cout<<minv<<endl;
*/
//solve
    int tmpN = N/10+1;
    int tmpm = m+1;
    int **dp;
    dp = new int* [tmpN];
    for(int i=0; i<tmpN; i++)
    {
        dp[i] = new int [tmpm];
    }
 
    //init
    for(int i=0; i<tmpN; i++)
    {
        dp[i][0] = 0;
    }
    for(int i=0; i<tmpN; i++)
    {
        for(int j=0; j<tmpm; j++)
        {
            if(i<minv)
            {
                dp[i][j] = 0;
            }
        }
    }
/*
    cout<<"init"<<endl;
*/
    //begin
    for(int i=minv; i<tmpN; i++)
    {
        for(int j=1; j<tmpm; j++)
        {
            if(arridx[j]==0)
            {
                int tmpmax;
                if(arrsubNum[j]==2)
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][1]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][1]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][1]]*arrw[arrsub[j][1]] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]]+arrv[arrsub[j][1]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]-arrv[arrsub[j][1]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]]+ arrv[arrsub[j][1]]*arrw[arrsub[j][1]] , tmpmax);
                }
                else if(arrsubNum[j]==1)
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                    if(i >= arrv[j]+arrv[arrsub[j][0]])
                        tmpmax = max(dp[i-arrv[j]-arrv[arrsub[j][0]]][j-1] + arrv[j]*arrw[j] + arrv[arrsub[j][0]]*arrw[arrsub[j][0]] , tmpmax);
                }
                else
                {
                    tmpmax = dp[i][j-1];
                    if(i >= arrv[j])
                        tmpmax = max(dp[i-arrv[j]][j-1] + arrv[j]*arrw[j] , tmpmax);
                }
 
                dp[i][j] = tmpmax;
            }
            else
            {
                dp[i][j] = dp[i][j-1];
            }
 
        }
    }
 
 
 
    cout<<dp[tmpN-1][tmpm-1]*10<<endl;
 
 
 
 
 
 
 
 
    for(int i=0; i<tmpN; i++)
    {
        delete [] dp[i];
    }
    delete [] dp;
 
 
 
    delete [] arrv;
    delete [] arrw;
    delete [] arridx;
 
    for(int i=0; i<m+1; i++)
    {
        delete [] arrsub[i];
    }
    delete [] arrsub;
    delete [] arrsubNum;
 
    return 0;
}

  

posted @   Hardsoftware  阅读(271)  评论(0编辑  收藏  举报
编辑推荐:
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
阅读排行:
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率
· AI Agent爆火后,MCP协议为什么如此重要!
点击右上角即可分享
微信分享提示