动态规划基本思想:
c++代码如下:
此问题为动态规划类的,与分而治之思想不同,它不允许出现大量重叠的子问题,下面的代码仔细看看就能看懂。。
#include<bits/stdc++.h>
using namespace std;
#define M 21
int p[M][M]; //记录前i个商品背包容量为j时的最大价值
int Rec[M][M]; //记录商品是否被选择
int KnapsackDP(int n,int c,int *v,int *f);//求解表格
int Print(int n,int c,int *v,int *f);
main()
{
int n, v[M], f[M], c, y; //重量,价格,n件商品,c背包总容量
cout<<"请输入商品个数和背包容量";
cin>>n>>c;
cout<<"请依次输入每个商品体积和价格:"<<endl;
for(int i=1;i<=n;i++)
{
cin>>v[i]>>f[i];
}
for(int i=0;i<=c;i++)
p[0][i]= 0;
for(int i=0;i<=n;i++)
p[i][0]= 0;
KnapsackDP(n,c,v,f);
y = Print(n,c,v,f);
// cout<<endl<<y;
cout<<"\n成功!";
return 0;
}
int KnapsackDP(int n,int c,int *v,int *f)//求解表格
{
for(int i=1;i<=n; i++) //行
{
for(int j=1;j<=c;j++) //列
{
if( v[i]<=j && (f[i]+ p[i-1][j-v[i]] > p[i-1][j]) )//背包容量够,选择物品的条件
{
p[i][j] = f[i] + p[i-1][j-v[i]];
Rec[i][j]= 1;
}
else{
p[i][j] = p[i-1][j];
Rec[i][j] = 0;
}
}
}
}
int Print(int n,int c,int *v,int *f)//输出最优求解方案
{
int k = c, sum=0;
for(int i=n;i>=1;i--)
{
if(Rec[i][k] == 1)
{
cout<<"选择商品"<<i<<endl; k= k-v[i];//背包剩余容量
sum+=f[i];
}else
cout<<"不选商品"<<i<<endl;
}
cout<<"\n总的最大价值为:"<<sum;
return p[n][c];
}
- 运行结果如下:
-
5 13
请依次输入每个商品体积和价格:
10 24
3 2
4 9
5 10
4 9
选择商品5
选择商品4
选择商品3
不选商品2
不选商品1
总的最大价值为:28
成功!