01背包问题
n个重量和价值为Wi ,Vi 的物品,从中挑出总重量不得超过W的物体,求其中方案中的价值总和的最大值
- 递归版
#include<cstdio>
#include<algorithm>
#include<cstring>
#define max_n 100
#define max_w 100
using namespace std;//01背包 动态规划
int dp[max_n+1][max_w+1];
int w[max_n];
int v[max_n],n;
int rec(int x,int y){
if(dp[x][y]>=0){ //如果DP内已经有这个了,直接返回,提高效率
return dp[x][y];
}
int res;
if(x==n){
res=0;//x==n结束递归
}else if(y<w[x]){
res=rec(x+1,y);//不能装下这一物品
}else{
res=max(rec(x+1,y),rec(x+1,y-w[x])+v[x]);//max(取,不取)
}
return dp[x][y]=res; //返回并且存储DP
}
int main(){
int m;
int i;
memset(dp,-1,sizeof(dp));//全部置为-1,,,,,,,,很重要
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&w[i]);
}
for(i=0;i<n;i++){
scanf("%d",&v[i]);
}
printf("%d",rec(0,m));
return 0;
}
/*
yl:
4 5
2 1 3 2
3 2 4 2*/
2.rec(i,j,sum)不推荐
#include<cstdio>
#include<algorithm>
#include<cstring>
#define max_n 100
#define max_w 100
using namespace std;//01背包 动态规划
int dp[max_n+1][max_w+1];
int w[max_n];
int v[max_n],n,sum;
int rec(int i,int j,int sum){
int res;
if(n==i){
res=sum;
}else if(j<w[i]){
res=rec(i+1,j,sum);
}else{
res=max(rec(i+1,j,sum),rec(i+1,j-w[i],sum+v[i]));
}
return res;
}
int main(){
int m;
int i;
memset(dp,-1,sizeof(dp));//全部置为-1,,,,,,,,很重要
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&w[i]);
}
for(i=0;i<n;i++){
scanf("%d",&v[i]);
}
printf("%d",rec(0,m,0));
return 0;
}
/*
yl:
4 5
2 1 3 2
3 2 4 2*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#define max_n 100
#define max_w 100
using namespace std;//01背包 动态规划
int dp[max_n+1][max_w+1];
int w[max_n];
int v[max_n],n;
int main(){
int m;
int i,j;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
scanf("%d",&w[i]);
}
for(i=0;i<n;i++){
scanf("%d",&v[i]);
}
for(i=n-1;i>=0;i--)
{
for(j=0;j<=m;j++){
if(j<w[i]) dp[i][j]=dp[i+1][j];
else {
dp[i][j]=max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]);
}
}
}
printf("%d",dp[0][m]);
return 0;
}
/*
yl:
4 5
2 1 3 2
3 2 4 2*/
4 ## 正向
for(i=0;i<n;i++){
for(j=0;j<=m;j++){
if(j<w[i]) dp[i+1][j]=dp[i][j];
else {
dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]);
}
}
}
printf("%d",dp[n][m]);