题解/算法 {3186. 施咒的最大总伤害}

题解/算法 {3186. 施咒的最大总伤害}

@LINK: https://leetcode.cn/problems/maximum-total-damage-with-spell-casting/;

这个题啊 他卡时间…

很容易想到DP求解, 用map<int,int> Cont来存储 然后配合DFS记忆化, 求最大值, 普普通通的DP题

long long maximumTotalDamage(vector<int>& A) {
    map<int,int> Cont;
    for( auto i : A){ Cont[i] ++;}

    unordered_map<int,long long> REC;
    auto Dfs = [&]( auto _dfs, int _a)->long long{
        if( REC.count( _a) > 0){
            return REC[_a];
        }

        long long ANS = 0;
        {
            auto it = Cont.lower_bound( _a+1);
            if( it != Cont.end()){
                ANS = std::max( ANS, _dfs( _dfs, it->first));
            }
        }
        {
            long long sum = _a *1LL* Cont[_a];
            auto it = Cont.lower_bound( _a+3);
            if( it != Cont.end()){
                sum += _dfs( _dfs, it->first);
            }
            ANS = std::max( ANS, sum);
        }
        REC[ _a] = ANS;
        return REC[_a];
    };
    return Dfs( Dfs, Cont.begin()->first);
}

可是 他超时了…

分析下时间, DP状态有1e5个, 然后注意 不仅lower_bound 还有REC[] 他俩都是log级别的, 按理说没事, 可力扣他的测试数据 是算在同一个程序的时间 总之他时间限制太严格…

优化吧…

我们把这个lower_bound优化掉 就需要把之前 DP状态里是存的数值 即map里的元素, 把他变成下标[0, 1e5);
借助vector的一个构造函数 vector( mp.begin(), mp.end()) 他存的是pair即键值对;

于是 我们找> cur+2的元素, 就直接通过下标判断 要么是ind+1/ ind+2;

别忘了REC[]下标操作, 之前他是map 现在变成数组;

long long maximumTotalDamage(vector<int>& A) {
    vector< pair<int,int> > C;
    {
        map<int,int> Cont;
        for( auto i : A){ Cont[i] ++;}
        C = vector< pair<int,int> >( Cont.begin(), Cont.end());
    }

    int N = C.size();
    static long long REC[int(1e5)+5];
    std::memset( REC, -1, sizeof(REC[0])*N);
    auto Dfs = [&]( auto _dfs, int _ind)->long long{
        if( REC[_ind] == -1){
            REC[ _ind] = 0;
            { // no
                if( _ind + 1 < N){
                    REC[_ind] = max( REC[_ind], _dfs( _dfs, _ind+1));
                }
            }
            { // yes
                long long v = C[_ind].first*1LL*C[_ind].second;
                FOR_( i, _ind+1, N-1){
                    if( C[i].first - C[_ind].first > 2){
                        v += _dfs(_dfs,i);
                        break;
                    }
                }
                REC[ _ind] = std::max( REC[ _ind], v);
            }
        }
        return REC[_ind];
    };
    return Dfs( Dfs, 0);
}

但是把, 他又超时了… 理论上分析 他就是1e5啊, 可能是因为递推的缘故, 你的auto _dfs 要写成引用的方式 即auto & _dfs 才可以;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值