dp总结篇

dp,直接递推和记忆化搜索

记忆化搜索

leetcode 1553 吃掉N个橘子的最少天数

思路:除2或除3总比减一划算,所以先减掉余数再除。由于N很大,需要记忆化搜索;由于N很大,不能用数组,可以用unordered_map

class Solution {
public:
    // vector<int>dp;
    unordered_map<int, int>mp;
    int dfs(int n) {
        if(mp[n])  return mp[n];
        int& ans = mp[n];
        if(n == 0)  return ans=-1;  // 特殊,1需要1次,0最小需要-1次
        return ans = min(dfs(n/3)+n%3, dfs(n/2)+n%2)+1;
    }
    int minDays(int n) {
        // dp.resize(n+1, -1);
        return dfs(n);
    }
};
View Code

数位DP

leetcode 902 最大为N的数组组合

思路:数位dp,逐位考虑,同时记录前面的一些必要信息。pre记录是否已经小于,flag记录前面是否是全0. (细节挺多,每种情况都要考虑到,到最后发现很多情况能合并)

class Solution {
public:
    typedef long long  ll;
    ll qpow(ll a, ll b) {
        ll ret = 1;
        while(b) {
            if(b&1) ret *= a;
            b >>= 1;
            a *= a;
        }
        return  ret;
    }
    ll dfs(vector<string>& digits, vector<int>& limits, int pos, bool pre, bool flag) { // 
        // cout << "pos: " << pos << endl;
        int n = digits.size(), m = limits.size();
        if(pos >= m)  return !flag;
        int limit = limits[pos];
        ll ret = 0;
        // 前面小
        if(pre)
        {
            // 填0
            if(flag)  ret += dfs(digits, limits, pos+1, pre, flag);
            // 不填0
            ret += qpow(n, m-pos);
        } else { // 前面等
            int i = 0;
            for(;i < n;i++)
                if(stoi(digits[i]) >= limit)  break;

            // 填limit
            if(i < n && stoi(digits[i]) == limit)  ret += dfs(digits, limits, pos+1, pre, false);
            // 填0
            if(flag)  ret += dfs(digits, limits, pos+1, true, flag);
            // 填(0, limit)
            ret += i*qpow(n, m-pos-1);
        }
    
        return ret;
    }
    int atMostNGivenDigitSet(vector<string>& digits, int n) {
        int tmp = n;
        vector<int>limits;
        while(tmp) {
            limits.insert(limits.begin(), tmp%10);
            tmp /= 10;
        }

        // for(int num : limits)  cout << num << " ";
        ll ans = dfs(digits, limits, 0, false, true);

        return ans;
    }
};
View Code

 

posted @ 2021-03-25 19:17  Rogn  阅读(56)  评论(0编辑  收藏  举报