题解 | #购物单#

购物单

http://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4

C++-购物单

1、主要思路是把这个问题简化为1-0背包问题,其中是附件的物品,不作为单独的一个物品;只有当遇到包含附件的主物品时,才对包含的附件一块进行判断。

2、首先把输入进行保存,第0维表示物品价格,第1维表示物品的满意度,第2维表示是否为附件,如果判断出当前物品是附件,就把当前物品坐标保存到主物品的第3、4维的位置。

3、初始化一个二维dp数组,第0个维度表示花的钱数,第1个维度表示可供选择的物品个数。当遇到当前钱数小于当前物品的价格或者当前物品是附件时,dp[i][j] = dp[i][j-1];其他情况时,依次进行判断并保留最大的满意度。

4、该算法还可以对空间和时间进行优化,有空做一下。

#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> vec(m+1,vector<int>(3));
    for(int i=1;i<m+1;i++){
        int t1,t2,t3;
        cin>>t1>>t2>>t3;
        vec[i][0] = t1/10;
        vec[i][1] = t2;
        vec[i][2] = t3;
        if(t3 != 0)
            vec[t3].push_back(i);
    }

    vector<vector<int>> dp(n/10 + 1,vector<int>(m+1,0));
    for(int i=1;i<n/10+1;i++){
        for(int j=1;j<m+1;j++){
            if(vec[j][2] != 0 || i<vec[j][0])
                dp[i][j] = dp[i][j-1];
            else{
                int temp = i-vec[j][0];
                dp[i][j] = max(dp[temp][j-1] + vec[j][0]*vec[j][1],
                               dp[i][j-1]);
                int len = vec[j].size();
                if(len == 4 && temp>=vec[vec[j][3]][0])
                    dp[i][j] = max(dp[i][j],
                                   dp[temp-vec[vec[j][3]][0]][j-1]
                                   + vec[j][0]*vec[j][1]
                                   +vec[vec[j][3]][0]*vec[vec[j][3]][1]);
                if(len == 5){
                    if(temp>=vec[vec[j][3]][0])
                        dp[i][j] = max(dp[i][j],
                                       dp[temp-vec[vec[j][3]][0]][j-1]
                                       + vec[j][0]*vec[j][1]
                                       +vec[vec[j][3]][0]*vec[vec[j][3]][1]);
                    if(temp>=vec[vec[j][4]][0])
                        dp[i][j] = max(dp[i][j],
                                       dp[temp-vec[vec[j][4]][0]][j-1]
                                       + vec[j][0]*vec[j][1]
                                       +vec[vec[j][4]][0]*vec[vec[j][4]][1]);
                    if(temp>=vec[vec[j][4]][0] + vec[vec[j][3]][0])
                        dp[i][j] = max(dp[i][j],
                                       dp[temp-vec[vec[j][4]][0]-vec[vec[j][3]][0]][j-1]
                                       + vec[j][0]*vec[j][1]
                                       +vec[vec[j][4]][0]*vec[vec[j][4]][1]
                                       +vec[vec[j][3]][0]*vec[vec[j][3]][1]);
                }
            }
        }
    }    
    cout<<dp[n/10][m] * 10<<endl;
    return 0;
}
全部评论

相关推荐

01-07 15:50
四川大学 Java
看日出看日落:好好背八股,做算法。我身边跟你bg差不多的基本都大厂暑期
点赞 评论 收藏
分享
一天代码十万三:实习东西太少了,而且体现不出你业务,3个月不可能就这点产出吧,建议实习多写点,玩具项目面试官都不感兴趣的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务