hiho刷题日记——第七天完全背包

和上个01背包相似。

这个完全背包的不同在于,对于一个物品,可以对面无数次。


所以我直接再昨天的程序上进行一个小改动就行了。


先放出昨天01背包的代码:ans是一个用来记忆化的数组并事先清0。

int f()
{
for(int n=0;n<N;n++)
for(int i=M;i>=need[n];i--)       
{
int t1=ans[i];
int t2=ans[i-need[n]]+value[n];
ans[i]=t1>t2?t1:t2;
}
return ans[M];
}


因为在01背包的时候物品只能兑换一个,递推式子为:

ans(n,m)=max{ans(n-1,m),ans(n-1,m-need(n))+value(n)}

所以在计算的时候从M循环到need[n],这样就不会出现多个选择的情况。

而在完全背包的时候,物品能兑换多个,递推式子为:

ans(n,m)=max{ans(n-1,m),ans(n,m-need(n))+value(n)}

所以在计算的时候只要从need[n]循环到M就好了,这样就在计算的时候就会出现选择多个的情况。

即完全背包的全代码为:

#include<cstdio>
#include<cstring>
using namespace std;

int N,M;
int need[501],value[501];
int ans[100001];

int f()
{
for(int n=0;n<N;n++)
for(int i=need[n];i<=M;i++) 
{
int t1=ans[i];
int t2=ans[i-need[n]]+value[n];
ans[i]=t1>t2?t1:t2;
}
return ans[M];
}


int main()
{
memset(ans,0,sizeof(ans));
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++)
scanf("%d%d",&need[i],&value[i]);

printf("%d",f());

return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值