P1616 疯狂的采药(洛谷,动态规划递推,完全背包)

先上题目链接:P1616 疯狂的采药

然后放AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll f[100010];
ll timee[10010];
ll w[10010];
int main()
{
    ll t,m;
    cin>>t>>m;//t总时间,m总草药
    //time时间,w价值
    for(ll i=1;i<=m;i++)
    {
        scanf("%lld",&timee[i]);
        scanf("%lld",&w[i]);
    }
    for(ll i=1;i<=m;i++)
        for(ll j=timee[i];j<=t;j++)
        {
            f[j]=max(f[j],f[j-timee[i]]+w[i]);
        }
    cout<<f[t]<<endl;
}
疯狂的采药

然后推荐一道类似的题目:采药

不同点在与这题是完全背包,采药那题是01背包,

还有就是疯狂的采药数据比较大,建议用滚动数组,如果用二维数组不知道会不会不行,我没试过.

然后讲一下思路:

假定你已经学过滚动数组01背包了,那么这题就很简单了,相对于普通的01背包来说,如果用滚动数组的话,

对于for的第二维也就是代表剩余空间那一维是从大到小遍历的,这样就能防止每个物品放了超过一次以上,

也就是新数据覆盖旧数据后在这次循环中新数据不会被再覆盖,放在实际层面就是一个物品只能被放一次

如果现在把for的第二维也就是代表剩余空间那一维是从小到大遍历,那么新数据也可能被覆盖,也就是一个物品放了后还可能接着放,

这样一来就从01背包转移到完全背包了

至于能用滚动数组的原因是第i层只和第i-1层有关

原文地址:https://www.cnblogs.com/zyacmer/p/9987032.html