zoukankan      html  css  js  c++  java
  • 动态规划

    0、目录

    线性dp、区间dp、树形dp、数位dp、概率dp、状压dp、插头dp、优化

    1、线性dp

    2、区间dp

    2.1、一类区间配对问题

    bool ok(int l,int r){
        
    }
    
    LL dfs(int l,int r){
        if(l==r) ;
        if(l==r-1){
            
        }
        if(dp[l][r]>=0) return dp[l][r];
    
        LL& res=dp[l][r]=0;
        if(ok(l,r)) res=max(res,dfs(l+1,r-1)+value);
        for(int i=l;i<r;i++){
            res=max(res,dfs(l,i)+dfs(i+1,r));
        }
        return res;
    }
    

    3、树形dp

    4、数位dp

    4.1、记忆化搜索模板

    int arr[maxn],tot;
    ///type根据dp具体维数调整
    int dp[maxn][type];
    ///ismax标记表示前驱是否是边界值
    ///ser标记前驱是否是前导零
    LL dfs(int len,int type, bool ismax,bool iszer) {
        if (len == 0) {
            ///递归边界,这说明前驱都合法了
            return 1LL;
        }
        if (!ismax&&dp[len][type]>=0) return dp[len][type];
        LL res = 0;
        int ed = ismax ? arr[len] : 9;
    
        ///这里插入递推公式
        for (int i = 0; i <= ed; i++) {
            if(i==0&&iszer){
                ///处理前导零
            }else{
                res += dfs(len - 1, type, ismax&&i == ed,iszer&&i==0);
            }
        }
        return ismax ? res : dp[len][type] = res;
    }
    
    LL solve(LL x) {
        tot = 0;
        while (x) { arr[++tot] = x % 10; x /= 10; }
        return dfs(tot, type, true,true);
    }
    
    void init() {
        memset(dp,-1);
    }
    

    5、概率dp

    6、状压dp

    7、插头dp

    7.1、简单的插头dp模板

    Eat the Trees

    8、优化

    8.1、矩阵快速幂:

    struct Matrix {
        LL mat[maxn][maxn];
        Matrix() { memset(mat, 0, sizeof(mat)); }
        friend Matrix operator *(const Matrix& A, const Matrix& B);
        friend Matrix operator +(const Matrix &A,const Matrix &B);
        friend Matrix pow(Matrix A, int n);
    };
    
    Matrix I;
    
    Matrix operator +(const Matrix& A, const Matrix& B) {
        Matrix ret;
        for (int i = 0; i < maxn; i++) {
            for (int j = 0; j < maxn; j++) {
                ret.mat[i][j] = (A.mat[i][j] + B.mat[i][j])%mod;
            }
        }
        return ret;
    }
    
    Matrix operator *(const Matrix& A, const Matrix& B) {
        Matrix ret;
        for (int i = 0; i < maxn; i++) {
            for (int j = 0; j < maxn; j++) {
                for (int k = 0; k < maxn; k++) {
                    ret.mat[i][j] = (ret.mat[i][j]+A.mat[i][k] * B.mat[k][j]) % mod;
                }
            }
        }
        return ret;
    }
    
    Matrix pow(Matrix A, int n) {
        Matrix ret=I;
        while (n) {
            if (n & 1) ret = ret*A;
            A = A*A;
            n /= 2;
        }
        return ret;
    }
    
    void init(){
        for(int i=0;i<maxn;i++) I.mat[i][i]=1;
    }
  • 相关阅读:
    ubuntu系统安装微信小程序开发工具
    【工具】vscode-代码编辑器详解
    微信小程序开发
    webpack基本配置
    vue相关知识
    史上最强vue总结~万字长文---面试开发全靠它了
    ES6——字符串
    ES6——Proxy与Reflect
    ES6——Map与Set
    ES6——Symbol
  • 原文地址:https://www.cnblogs.com/fenice/p/5824198.html
Copyright © 2011-2022 走看看