实验名称
用动规法实现0-1背包。
实验目的
用动规法实现0-1背包:给你n个物品,每个物品有其重量和价值,现在有一个能装一定重量物品的背包,物品不能分割,要求能装下的最大价值。并输出最大价值下装载了哪几个物品。
实验原理
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题。
但是经分解得到的子问题往往不是互相独立的。不同子问题的数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
实验步骤
①用v[i]表示物品价值,w[i]表示物品重量。定义状态dp[i][j]以j为容量为放入前i个物品(按i从小到大的顺序)的最大价值;
②初始化边界条件,dp(0,j)=dp(i,0)=0;
③对于每一个物品,有两种选择方法,能装下和不能装下
1、包的容量比该商品体积小时装不下,此时的价值与前i-1个的价值是一样的,即dp(i,j)=dp(i-1,j);
2、还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,所以在装与不装之间选择最优的一个,即dp(i,j)=max{dp(i-1,j),dp(i-1,j-w(i))+v(i)};其中dp(i-1,j)表示不装,dp(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i)但价值增加了v(i);
④得到转移方程:
dp(i,j)=dp (i-1,j) j<w(i)
dp(i,j)=max{dp(i-1,j),dp(i-1,j-w(i))+v(i) } j>=w(i)
时间复杂度分析
利用动态规划解决此问题的递归式可得到动态规划的时间复杂度为O(n*c)。
实验心得 通过这次实验,我回顾了0-1背包问题与动态规划算法,让我对动态规划算法更加熟悉。
#include<iostream>
#include<fstream>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
using namespace std;
void creatrand(long int m)
{
ofstream f_out;
f_out.open("input.txt", ios::out);
srand(time(NULL));
int r,s;
for ( int i = 0; i < m; i++)
{
r =rand()%(10-1)+1;
s =rand()%(10-1)+1;
f_out<<r<<" "<<s<<endl;
}
f_out.close();
}
int main()
{
int C,n;//c是容量,n是规模
ofstream f_out;
f_out.open("output.txt");
ifstream f_in("input.txt");
cin >> C >> n;
creatrand(n);
int w[n],val[n];
for( int i=1; i<=n; i++)
{
f_in >> w[i]>>val[i];
cout<< w[i]<<" "<<val[i]<<endl;
f_out<< w[i]<<" "<<val[i]<<endl;
}
int dp[n][C];
//初始化dp
for( int i = 0;i <= C;i++){//当没有物品时,任何容量价值均为0
dp[0][i] = 0;
}
for( int i = 0;i <= n;i++){//当容量为0时,任何物品都装不进去,价值为0
dp[i][0] = 0;
}
LARGE_INTEGER time,time0,time1,time2;
QueryPerformanceFrequency(&time);
QueryPerformanceCounter(&time0);
for( int i=1; i<=n; i++) //物品
for( int j=C; j>=0; j--) //容量
{
if(j >= w[i])
dp[i][j] = max(dp[i-1][j-w[i]]+val[i], dp[i-1][j]);
else //只是为了好理解
dp[i][j] = dp[i-1][j];
}
QueryPerformanceCounter(&time1);
cout << dp[n][C] << endl;
cout<<"时间为:"<<1000.0*(time1.QuadPart-time0.QuadPart)/time.QuadPart<<"ms"<<endl;
f_out<<dp[n][C]<<endl;
f_out<<"时间为:"<<1000.0*(time1.QuadPart-time0.QuadPart)/time.QuadPart<<"ms"<<endl;
return 0;
}