题目:http://acm.hdu.edu.cn/showproblem.php?pid=2602
从前到后推导
参考:https://blog.csdn.net/tobe_numberone/article/details/89430223
#include<string.h>
#include <iostream>
#include <algorithm>
using namespace std;
//http://acm.hdu.edu.cn/showproblem.php?pid=2602
//下面是记忆化搜索,完全可行
int recode[1000][1000]{0};
int value[1000];//价值
int v[1000];//体积
int cases,nums,bagv;
int resolve(int i,int remainV);
int main(){
cin>>cases;
while (cases--){
cin>>nums>>bagv;
for(int i = 0;i<nums;i++)
scanf("%d",&value[i]);
for(int i = 0;i<nums;i++)
scanf("%d",&v[i]);
memset(recode,0, sizeof(recode));//重置记忆化数组
printf("%d\n",resolve(0,bagv));
}
return 0;
}
int resolve(int i,int remainV)
{//resolve的含义:从第i个物品到第nums个物品,填满remainV,返回得到的最大价值
//
if (recode[i][remainV] != 0)
return recode[i][remainV];
int res;
if(i == nums){//物品已经选择完毕,这一轮就没有新的价值
res = 0;
} else if(v[i]>remainV){ //此物品在剩余的背包空间放不下
res = resolve(i+1,remainV);
} else{
res = max(resolve(i+1,remainV),resolve(i+1,remainV-v[i])+value[i]);//取放与不放的最大价值
}
return recode[i][remainV] = res;
}
从后往前推导:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<vector>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
//http://acm.hdu.edu.cn/showproblem.php?pid=2602
//w是价值,v是骨头容量
int v[1001] ,w[1001];
int dp[1001][1001]={0};
int Volum;
int Num;
int i,j;
int f(int i,int j)
{//i是物品编号,j是剩余背包容量
//从第i个物品到第1个物品,填满j体积,返回最大价值
if(i<=0)return 0;
int t;
t=dp[i][j];
if(t!=-1)
return t;
if(v[i]>j)
{
t=f(i-1,j);
}
else
{
t=max(f(i-1,j),f(i-1,j-v[i])+w[i]);
}
return dp[i][j]=t;
}
void clear(int x)
{
int i,j;
for(i=0;i<1001;i++)
{
for(j=0;j<1001;j++)
{
dp[i][j]=x;
}
}
}
int main(void)
{
int t;
cin>>t;
while(t--)
{
cin>>Num>>Volum;
for(i=1;i<=Num;i++)
{
cin>>w[i];//价值
}
for(i=1;i<=Num;i++)
{
cin>>v[i];//容积
}
clear(-1);
f(Num,Volum);
cout<<dp[Num][Volum]<<"\n";
//cout<<dp[0][Volum]<<"\n";
}
return 0;
}