先上题目链接:P1616 疯狂的采药
然后放AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll f[];
ll timee[];
ll w[];
int main()
{
ll t,m;
cin>>t>>m;//t总时间,m总草药
//time时间,w价值
for(ll i=;i<=m;i++)
{
scanf("%lld",&timee[i]);
scanf("%lld",&w[i]);
}
for(ll i=;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层有关