动态规划

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(lr) ;
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(i0&&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 = retA;
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  阅读(159)  评论(0)    收藏  举报