完全背包
使用公式求解
思路:每件物品都要判断使用还是不使用,还是使用多次,并且存储当前物品各个重量下的价值与已经记录的同一重量下的最大值中,大的值
所以物品在外循环,重量在内循环,内循环中每个重量下选这件物品或者多选这件物品得到的最大价值w1,与不选这件物品的已记录的最大价值w2相比较,把大的值max记录下(替换w2,即w2=max)。
例题,解决切原木问题 链接:
切原木问题
给定一根长度为N米的原木;另有一个分段价格表,给出长度L1,L2,…Li,…Lk米所对应的价格P1,P2…Pk(Li,Pi均为正整数),求切割原木分段出售所能获得的最大收益。 例如,根据下面给出的价格表,
Li 1 2 3 4 5 6 7 8 9 10
Pi 1 5 8 9 10 17 17 20 23 28
若要出售一段8米长的原木,最优解是将其切割为2米和6米的两段,这样可以获得最大收益=L2+L6=5+17=22。而若要出售一段3米长的原木,最优解是根本不要切割,直接售出。
————————————————
代码:
#include <stdio.h>
#include <stdlib.h>
int v,n;
int length[1010];//存储题目输入的每个分段
int value[1010];//存储输入的对应分段的价值
int maxvalue[100100];//存储每个长度下的最大价值
int max(int a,int b)//返回最大值函数
{
return a>=b?a:b;
}
int main()
{
scanf("%d%d",&v,&n);
for(int i=0;i<n;i++)
scanf("%d",&length[i]);
for(int i=0;i<n;i++)
scanf("%d",&value[i]);
for(int i=0;i<n;i++)///外循环:循环每个分段(每个分段都要判断选或不选,或多选)
for(int j=length[i];j<=v;j++)///内循环:从可以选该分段的长度开始,直到最大长度v
maxvalue[j]=max(maxvalue[j],maxvalue[j-length[i]]+value[i]);///选当前分段(价值为:value[i]+maxvalue[j除去当前分段的剩余长度]的值)与不选当前分段(价值为:maxvalue中下标为j的值)的价值做比较,并用大的值替换maxvalue[j],成为j长度下的最大值
printf("%d",maxvalue[v]);
}
202111081943一