简单线性dp:
反复利用前态推出后态
上升子序列:
for(int i=1;i<=n;i++)
dp[i]=a[i];
for(int j=1;j<I;j++)
If(a[i]>a[j])
dp[i]=max(dp[i],dp[j]+1)
01背包:
从后往前遍历
For(int i=1;i<=type;i++)
For(int j=weight;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+val[i]
完全背包:
从前往后遍历
for(int i=1;i<=type;i++)
for(int j=w[i];j<=weight;j++)
dp[j]=max(dp[j],dp[j-w[i]]+val[i]
多重背包:
二进制拆分 + 01背包
For(int j=1;j<=num;j<<=1)
{
val[i]=j*v;
wei[i]=j*w;
num-=j;
}
if(num>0) {val[++i]=num*v;wei[i]=num*v}
泛背包:
从右上开始遍历
HDU1712
for(int i=1;i<=n;i++)//种类
for(int j=m;j>=1;j--) //剩余容量
for(int k=1;k<=j;k++) //在第i种上花费容量k
dp[j]=max(dp[j],dp[j-k]+a[i][k]);
分组背包:
①每组最少拿一个
HDU3033
int n,m;//n组,容量m
for(int i=1;i<=n;i++)
{
for(int k=0;k<=m;k++) dp[i][k]=-inf;
for(int k=1;k<=t;k++)//第n组中第t个元素
for(int j=m;j>=w[i];j--)
dp[i][j]=max(dp[i][j],max(dp[i-1][j-w[i]]+v[i],dp[i][j-w[i]]+v[i])
②每组最多拿一个
xinjun与阴阳师
每个状态和上一层比较;
for(int i=1;i<=n;i++)
{
for(int k=0;k<=m;k++) dp[i][k]=dp[i-1][k];
for(int k=1;k<=t;k++)
for(int j=m;j>=w[i];j--)
dp[i][j]=max(dp[i][j],dp[i-1][j-w[i]]+v[i]
}
③多种多组背包的组合
HDU3535
记忆化搜索:
Power OJ2842
dfs+dp数组进行记忆