完全背包经历了两次化简。
1.从二维变一维。
2.从三层循环变两层循环。
二维三层循环:
/*
初始化
*/
for(int i=1;i<=n;i++) {
for(int j=1;j<=K;j++) {
for(int k=1;k<=j/w[i];k++){
dp[i][j]=Math.min(dp[i-1][j-w[i]*k]+p[i]*k, dp[i][j]);
}
}
}
二维二层循环:
/*
初始化
*/
for(int i=1;i<=n;i++) {
for(int j=w[i];j<=K;j++) {
dp[i][j]=Math.min(dp[i][j-w[i]]+p[i], dp[i][j]);
}
}
一维二层循环:
/*
初始化
*/
for(int i=1;i<=n;i++) {
for(int j=w[i];j<=K;j++) {
dp[j]=Math.min(dp[j-w[i]]+p[i], dp[j]);
}
}
不懂的时候,请去动手画一画表格,就明白了。
关于初始化:
1.“恰好装满”求最小值:
dp[0] = 0;
dp[i] = INF; i∈[1,n];
因为在求dp[i]时,从dp[0]转移过来的意思是在容积为j的包里只装满第i种硬币时的价值。所以dp[0]是合法状态,不应初始化为INF
2.“ 不用恰好装满”求最小值:
dp[i] = INF; i∈[0,n];
3.恰好装满”求最大值:
dp[0] = 0;
dp[i] = -INF; i∈[1,n];
4.“不用恰好装满”求最大值:
dp[i] = 0; i∈[0,n];