zz的01背包问题 基础动态规划题 经典01背包

题目
zz的01背包问题

描述
zz每天都会去零食店寻找自己喜欢吃的零食。可惜的是zz的背包容量(V<=10000)是有限的,他只能装一定重量的零食。为了买到自己满意度更高的零食组合,zz给每种零食都赋予了一个满足度,表示zz买了这种零食后可以收获的满足度是多少。零食的种类有n(n<=100)种,每种零食都有一个占用空间(Wi<=100),和一个zz的满足度(Di<=1000)。请你帮zz小朋友计算一下,他能得到的最大满足度是多少?

输入格式
第一行包含两个整数n,v,分别表示零食的种类和zz的背包的容量。
接下来n行,每行两个整数Wi和Di,分别表示第i种零食的占用空间和买了这种零食后zz获得的满足度。

输出格式
一行一个整数,表示zz能够获得的最大满足度。

输入样例
6 10
1 4
4 3
5 6
2 2
3 2
5 7

输出样例
14

题目思路

第一种思路 dp二维数组

#include 
#include 
using namespace std;
int dp[101][10001];
int main(){

	int n,v,w[101],d[101]; //定义变量 

	cin>>n>>v; 
	for(int i=1;i<=n;i++) cin>>w[i]>>d[i];//输入 

	for(int i=1;i<=n;i++){
		for(int j=1;j<=v;j++){
			dp[i][j]=dp[i-1][j];
			if(j>=w[i])
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+d[i]); 
				//状态转移方程 
		}
	}

	cout<

第二种思路 优化成dp一位数组

#include 
#include 
using namespace std;
int dp[10001];
int main(){
int n,v,w[101]={},d[101]={}; //数组定义 

	cin>>n>>v;
	for(int i=1;i<=n;i++) cin>>w[i]>>d[i]; //输入 

	for(int i=1;i<=n;i++){
		for(int j=v;j>=1;j--){
			if(j>=w[i])
				dp[j]=max(dp[j],dp[j-w[i]]+d[i]); //优化状态转移方程 
		}
	}
	cout<

第三种思路 记忆化搜索

#include 
#include 
#include 
#include 
#include 
using namespace std;
int dp[105][3][10005]={};
int n,v;int w[105]={},d[105]={}; //定义变量
int dfs(int step_n,int point_w,int bag_v){

	if(step_n>n||bag_v>v) return 0;
	if(dp[step_n][point_w][bag_v]!=-1) return dp[step_n][point_w][bag_v]; 
	//递归终止条件 
	
	int tmp1=0,tmp2=0;
	if(bag_v+w[step_n]<=v)
	tmp1=dfs(step_n+1,1,bag_v+w[step_n])+d[step_n]; 
	tmp2=dfs(step_n+1,2,bag_v); //递归 
	
	dp[step_n][point_w][bag_v]=max(tmp1,tmp2); //赋值 
	return dp[step_n][point_w][bag_v]; //返回值 
}
int main(){

	cin>>n>>v;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&w[i],&d[i]);
	} //输入
	 
	for(int i=0;i<105;i++){
		for(int j=0;j<3;j++){
			for(int k=0;k<10005;k++){
				dp[i][j][k]=-1;
			}
		}
	} //数组初始化 
	
	cout<

你可能感兴趣的:(c++)