题目:/*有n件物品和一个容量为v的背包。第i件物品的体积是V[i],价值是S[i]。求价值总和最大为多少*/
特点:每种物品仅有一件,可以选择放或不放。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
int MAX(int a,int b)
{
return a>b?a:b;
}
int main()
{
int V[20],S[20],ss[20][20];
int v,n;
while(~scanf("%d%d",&n,&v))
{
for(int i=0; i<n; i++)
scanf("%d",&V[i]);//体积
for(int i=0; i<n; i++)
scanf("%d",&S[i]);//花费
memset(ss,0,sizeof(ss));//初始化数组
for(int i=1; i<n; i++)
{
for(int j=1; j<=v; j++)
{
if(j<V[i])//背包装不下第i个物体,目前只能靠前i-1个物品
ss[i][j]=ss[i-1][j];
else
ss[i][j]=MAX(ss[i-1][j],ss[i-1][j-V[i]]+S[i]);//状态转移方程
}
}
for(int i=1; i<n; i++)
{
for(int j=1; j<=v; j++)
printf("%2d ",ss[i][j]);
printf("\n");
}
}
return 0;
}
状态转移方程:
ss[i][v]=MAX(ss[i-1][v],ss[i-1][v-V[i]]+S[i]);
ss[i][v]是指在有v体积可用的情况下在前i个物品取的最大价值;
ss[i-1][v]是指在有v体积可用的情况下在在前i-1个物品取的最大价值(即不取第i个物品);
ss[i-1][v-V[i]]是指在 有v-[i]体积可用的情况下 前i-1个物品的最大价值+S[i]加上i物品的价值(即使v体积可用的情况下取用第i个物品的最大价值)
示例:
6 12
0 1 3 2 6 2
0 2 5 3 10 4
求出在1-v体积的各个体积
取走1-i物品的最大价值
上表中横向(x)为2时,纵向(y)为2时候:可取用1,2,3物品,可用体积为2,这时只能取走1,2,价值为2; j<V[i]的情况
上表中横向(x)为3时,纵向(y)为2时候:可取用1,2,3,4物品,可用体积为2,这时取走1,2,价值为2,取走物品4(价值为3体积为2)找到ss[2][0](取走物品4的情况下剩余空间所能得到的最大价值)+物品的价值大于2,所有是ss[3][2]为3)
ss[i][j]=ss[i-1][j-V[i]]+S[i] (ss[i-1][j]<ss[i-1][j-V[i]]+S[i])的情况;