DP差不多已经忘光了..
【矩阵型】
洛谷P1002 过河卒 博客题解:
洛谷P1006方格取数 博客题解:
【线性】
乌龟棋
https://www.luogu.org/problemnew/show/1541
dp[i][j][k][l][m]=max(dp[i−1][j−1][k][l][m]+a[i−1],....)
这个i可以去掉。
dp[i][j][k][l]=max(dp[i−1][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][j−1]×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得到最大值。
时间复杂度
O(n3)
【数位DP】
参考:http://blog.csdn.net/eagle_or_snail/article/details/50987044