hihoCode-1043-完全背包

我们定义:best(i,x)代表i件以前的物品已经决定好选择多少件,并且在剩余奖券x的情况下的最优解。
在这里插入图片描述
在这里插入图片描述
我们可以考虑最后一步,是否再次选择i物品,在不超过持有奖券总额的情况下。上面的第二个式子的k是大于1的,第一个的k是大于0的,所以第二个还可以再选,体现在式子的左侧,它又减了一次need(i)。
对比右侧的两个式子我们发现,它们是一样的,所以当我们计算best(i,x-need(i))的时候,其实之前的前k-1次选择都已经计算过了,所以这个式子就可以优化成下面的第三个式子。
这就是完全背包的式子,和01背包长的有点像。
至于这个式子其实可以不写if else,因为我们在计算的时候,前面的不能减的实际上是不能算的,至于能算的,未选择i的时候,实际上还是要和选择i的时候进行比较,所以我们没有必要计算,大概是这样的,大家自行脑补每次更新dp。

#include <cstdio>
int dp[100005], w[505], v[505];
int n, m;

int max(int x,int y)
{
    return x > y ? x : y;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n;i++)
        scanf("%d%d", &w[i], &v[i]);
    for (int i = 0; i < n;i++) {
        for (int j = w[i]; j <= m;j++) {
            dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
        }
    }
    printf("%d
", dp[m]);
    return 0;
}
原文地址:https://www.cnblogs.com/xyqxyq/p/10366570.html