题目解析
题意
输入数据的组数T,每组数据包含3行,第1行输入骨头的数量N和背包的体积V,第二行输入N个整数代表每个骨头的价值,第三行输入N个整数代表每个骨头的体积。求体积为V的背包所能装物品的最大价值。
思路
1、
01背包问题的特点:每种物品只有一个,可以选择放或者不放。用子问题定义状态,dp[n][v]表示前n件物品放入一个容量为v的背包可以获得的最大价值。状态转移方程dp[n][v]=max(dp[n-1][v],dp[n-1][v-vn]+jzn);(vn第n个物品的体积,jzn第n个物品的价值)。
2、
用子问题定义状态,dp[v]表示容量为v的背包可以获得的最大价值。状态转移方程dp[v]=max(dp[v],dp[v-vn]+jzn);
代码
1、
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 1004
struct node{
int jz,tj;
}a[M];
int dp[M][M];
int main(){
//freopen("data.txt","r",stdin);
int T,N,V,i,j;
while(~scanf("%d",&T)){
while(T--){
scanf("%d%d",&N,&V);
for(i=1;i<=N;i++)
scanf("%d",&a[i].jz);
for(i=1;i<=N;i++)
scanf("%d",&a[i].tj);
memset(dp,0,sizeof(dp));
for(i=1;i<=N;i++)
for(j=V;j>=0;j--){
if(j<a[i].tj){
dp[i][j]=dp[i-1][j];
continue;
}
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i].tj]+a[i].jz);
}
printf("%d\n",dp[N][V]);
}
}
return 0;
}
2、
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 1004
struct node{
int jz,tj;
}a[M];
int dp[M];
int main(){
//freopen("data.txt","r",stdin);
int T,N,V,i,j;
while(~scanf("%d",&T)){
while(T--){
scanf("%d%d",&N,&V);
for(i=0;i<N;i++)
scanf("%d",&a[i].jz);
for(i=0;i<N;i++)
scanf("%d",&a[i].tj);
memset(dp,0,sizeof(dp));
for(i=0;i<N;i++)
for(j=V;j>=a[i].tj;j--)
dp[j]=max(dp[j],dp[j-a[i].tj]+a[i].jz);
printf("%d\n",dp[V]);
}
}
return 0;
}