文章标题

来源:互联网 发布:淘宝集运德国 编辑:程序博客网 时间:2024/05/20 07:34

DP差不多已经忘光了..

【矩阵型】
洛谷P1002 过河卒 博客题解:
洛谷P1006方格取数 博客题解:
【线性】


乌龟棋
https://www.luogu.org/problemnew/show/1541

dp[i][j][k][l][m]=max(dp[i1][j1][k][l][m]+a[i1],....)

这个i可以去掉。
dp[i][j][k][l]=max(dp[i1][j][k][l]+a[..)


【LIS】
合唱队形

【LCS】

【背包】

采药
装箱问题
开心的金明
能量项链
金明的预算方案
守望者的逃离
小A点菜
疯狂的采药


【区间DP】

一般是枚举区间,把区间分成左右两部分,然后求出左右区间再合并。


石子归并(环形线性DP)和能量项链
https://www.luogu.org/problemnew/show/P1063

dp[i][j]=min(dp[i][k],dp[k+1][j])+sum[i][j]

其中dp[i][j] 表示区间[i,j)最小代价,k[i,j),用三个循环分别枚举i,j,k,时间复杂度为O(n3)


乘积最大
https://www.luogu.org/problemnew/show/1018
(一开始写错了)

dp[i][j]=max(dp[i][j],dp[k][j1]×num[k+1][i])

其中dp[i][j]表示前i个数通过k个称号乘起来的最大结果。
k是前面那个指针,i是后面那个。
num[i][j]表示第i到第j位连起来的数字,通过预处理得到:

typedef long long ll;for (int i =1;i<=n;i++){    num[i][i] = a[i];    for(int j=i+1;j<=n;j++)        num[i][j] = num[i][j-1] * 10 + a[j];  }
   for(int j=1; j<=K; j++)//这个K是大写的,表示总区间数        for(int i=j; i<=n; i++)            for(int k=j; k<i; k++) {                f[i][j]=max(f[i][j],f[k][j-1]*num[k+1][i]);            }

然后通过DP得到最大值。
时间复杂度On3


【数位DP】

参考:http://blog.csdn.net/eagle_or_snail/article/details/50987044