动态规划

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;
}
posted @ 2016-08-30 23:56  fenicnn  阅读(140)  评论(0编辑  收藏  举报