DP学习笔记
可是记下来有什么用呢?我又不会
笨蛋你以后就会了
完全背包问题
先理解初始的DP方程:
void solve()
{
for(int i=0;i<;i++)
for(int j=0;j<=w;j++)
for(int k=0;k*w[i]<=j;k++)
dp[i+1][j]=max(dp[i+1][j],dp[i][j-k*w[i]]+k*v[i]);
}
其中:k*w[i]<=j
是指:如果当前的物品小于背包容量,则选择该物品
dp[i+1][j]=max(dp[i+1][j],dp[i][j-k*w[i]]+k*v[i])
是指:如果取了这个物品后剩余容量的价值比当前的小,则选用当前的方案翻入dp[i+1][j]
中。
很明显会\(\color {darkblue}{TLE}\),所以得优化:
void solve()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<=w;j++)
{
if(j<w[i])
dp[i+1][j]=dp[i][j];
else
dp[i+1][j]=max(dp[i][j],dp[i+1][j-w[i]]+v[i]);
}
}
}
优化方法:
在计算dp[i+1][j]
的结果,是和dp[i+1][j-w[i]]
计算选择k-1
的时候是一样的。所以可以发现dp[i+1][j]
的结果已经在算dp[i+1][j-w[i]]
的时候算完了,所以可以变形。