题解 | #购物单#

购物单

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

HJ16 购物单
暴力递归改记忆化搜索

思路:
1.先把附件和组件组合在一起
2.买第一个附件和买第二个附件,以及两个都买的 和两都买不 只买主件的情况

#include<iostream>
#include <set>
#include <queue>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <algorithm>
#include <vector>
#include <algorithm>
#include <numeric>
#include <sstream>
#include <climits>
#include <cstring>
using namespace std;
#define random(a,b) (rand()%(b-a)+a)

unordered_map<string,int> cache;


int process2(vector<Node*> nodes, int index, int m, int N)
{
    string key = to_string(index) + "_" + to_string(N);
    //没钱了
    if(N < 0)
    {
        return -1;
    }
    //买完了,没钱了
    if(m == index  || N == 0)
    {
        return 0;
    }
    if(cache.find(key) != cache.end())
        return cache[key];
    //不买
    int p1 = process2(nodes, index + 1, m, N);

    //买第一个附件
    int p2 = -1;
    if(!nodes[index]->attach.empty())
    {
        int p2next = process2(nodes, index + 1, m, N - nodes[index]->attach[0]->value - nodes[index]->value);
        if(p2next != -1)
        {
            p2 = (nodes[index]->attach[0]->value * nodes[index]->attach[0]->weight) + (nodes[index]->value * nodes[index]->weight) + p2next;
        }
    }
    //买第二个附件
    int p3 = -1;
    int p4 = -1;
    if(nodes[index]->attach.size() == 2)
    {
        int p3next = process2(nodes, index + 1, m, N - nodes[index]->attach[1]->value - nodes[index]->value);
        if(p3next != -1)
        {
            p3 = (nodes[index]->attach[1]->value * nodes[index]->attach[1]->weight) + (nodes[index]->value * nodes[index]->weight) + p3next;
        }
        //两个附件都买
        int p4next = process2(nodes, index + 1, m, N - nodes[index]->attach[0]->value - nodes[index]->attach[1]->value - nodes[index]->value);
        if(p4next != -1)
        {
            p4 = (nodes[index]->attach[0]->value * nodes[index]->attach[0]->weight) + (nodes[index]->attach[1]->value * nodes[index]->attach[1]->weight) + (nodes[index]->value * nodes[index]->weight) + p4next;

        }
    }
    //就买主件
    int p5 = -1;
    int p5next = process2(nodes, index + 1, m, N - nodes[index]->value);
    if(p5next != -1)
    {
        p5 = (nodes[index]->value * nodes[index]->weight) + p5next;
    }
    int a = std::max(p1, p2);
    int b = std::max(a,p3);
    int c = std::max(b,p4);
    int d = std::max(c,p5);
    cache[key] = d;
    return d;
}


int main()
{
    int N,m;
    cin>>N>>m;
    unordered_map<int, Node*> nodes;
    vector<Attach*> attachs;
    int val,weight,num;
    for(int i = 0; i < m; i++){

        cin>>val;
        cin>>weight;
        cin>>num;
        if(num == 0)
        {
            Node * node = new Node(val,weight,num);
            nodes[i] = node;
        }
        else
        {
            Attach * attach = new Attach(val,weight,num);
            attachs.push_back(attach);
        }
    }
    for(int i = 0; i < attachs.size(); i++)
    {
        nodes[attachs[i]->num-1]->attach.push_back(attachs[i]);
    }
    vector<Node*>arr;
    for(auto const &v : nodes)
    {
        arr.push_back(v.second);
    }
    cout<<process2(arr, 0, nodes.size(), N);
    return 0;
}
全部评论

相关推荐

会飞的猿:我看你想进大厂,我给你总结一下学习路线吧,java语言方面常规八股要熟,那些java的集合,重点背hashmap八股吧,jvm类加载机制,运行时分区,垃圾回收算法,垃圾回收器CMS、G1这些,各种乐观锁悲观锁,线程安全,threadlocal这些。在进阶一些的比如jvm参数,内存溢出泄漏排查,jvm调优。我这里说的只是冰山一角,详细八股可以去网上找,这不用去买,都免费资源。mysql、redis可以去看小林coding,我看你简历上写了,你一定要熟,什么底层b+树、索引结构、innodb、mvcc、undo log、redo log、行级锁表级锁,这些东西高频出现,如果面试官问我这些我都能笑出来。消息队列rabbitmq也好kafka也好,学一种就行,什么分区啊副本啊确认机制啊怎么保证不重复消费、怎么保证消息不丢失这些基本的一定要会,进阶一点的比如LEO、高水位线、kafka和rocketmq底层零拷贝的区别等等。计算机网络和操作系统既然你是科班应该理解起来问题不大,去看小林coding这两块吧,深度够了。spring boot的八股好好看看吧,一般字节腾讯不这么问,其他的java大厂挺爱问的,什么循环依赖啥的去网上看看。数据结构的话科班应该问题不大,多去力扣集中突击刷题吧。项目的话其实说白了还是结合八股来,想一想你写的这些技术会给你挖什么坑。除此之外,还有场景题、rpc、设计模式、linux命令、ddd等。不会的就别往简历上写了,虽然技术栈很多的话好看些,但背起来确实累。总结一下,多去实习吧,多跳槽,直到跳到一个不错的中厂做跳板,这是一条可行的进大厂的路线。另外,只想找个小厂的工作的话,没必要全都照这些准备,太累了,重点放在框架的使用和一些基础八股吧。大致路线就这样,没啥太多难度,就是量大,你能达到什么高度取决于你对自己多狠,祝好。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务