一、区间DP
区间 DP 常用模版
所有的区间dp问题枚举时,第一维通常是枚举区间长度,并且一般 len = 1 时用来初始化,枚举从 len = 2 开始;第二维枚举起点 i (右端点 j 自动获得,j = i + len - 1)
例题:
·石子合并
AcWing 282. 石子合并(闫氏DP分析法) - AcWing
·加分二叉树
AcWing 479. 加分二叉树(寒假每日一题) - AcWing
#include <iostream> #include <algorithm> using namespace std; const int N=54; int dp[N][N]; int w[N]; int g[N][N]; void dfs(int l,int r) { if(l>r) return ; int p=g[l][r]; cout<<p<<' '; dfs(l,p-1); dfs(p+1,r); } int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>w[i]; for(int len=1;len<=n;len++) for(int i=1;i+len-1<=n;i++) { int j=i+len-1; if(len==1) dp[i][j]=w[i],g[i][j]=i; //默认用自己作为根结点 else for(int k=i;k<=j;k++) { int left = k==i?1:dp[i][k-1]; int right = k ==j?1:dp[k+1][j]; int t=left*right+w[k]; if(t>dp[i][j]) { dp[i][j]=t; g[i][j]=k; } } } cout<<dp[1][n]<<endl; dfs(1,n); return 0; }
·能量项链
二、树型DP
三、状态压缩DP