状态转换方程: f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)} 动态规划是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些结果减轻运算量。 比如01背包问题。 因为背包最大容量M未知。所以,我们的程序要从1到M一个一个的试。比如,开始任选N件物品的一个。看对应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则,多出来的空间里能放N-1物品中的最大价值。怎么能保证总选择是最大价值呢?看下表。 测试数据: 10,3 3,4 4,5 5,6 c[i][j]数组保存了1,2,3号物品依次选择后的最大价值. 这个最大价值是怎么得来的呢?从背包容量为0开始,1号物品先试,0,1,2,的容量都不能放.所以置0,背包容量为3则里面放4.这样,这一排背包容量 为4,5,6,....10的时候,最佳方案都是放4.假如1号物品放入背包.则再看2号物品.当背包容量为3的时候,最佳方案还是上一排的最价方案c为 4.而背包容量为5的时候,则最佳方案为自己的重量5.背包容量为7的时候,很显然是5加上一个值了。加谁??很显然是7-4=3的时候.上一排c3的最 佳方案是4.所以。总的最佳方案是5+4为9.这样.一排一排推下去。最右下放的数据就是最大的价值了。(注意第3排的背包容量为7的时候,最佳方案不是 本身的6.而是上一排的9.说明这时候3号物品没有被选.选的是1,2号物品.所以得9.) 从以上最大价值的构造过程中可以看出。 f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}这就是书本上写的动态规划方程. //knapsack.in 10 3 3 4 4 5 5 6 //knapsack.cpp /* * File:knapsack.cpp * Descripe: Dynamic programming * transform function:f[i][j]=max{ (f[i-1][j-weight[i]]+v[i]),f[i-1][j]} * Athor: [email protected] * * */ #include <fstream> #include <iostream> using namespace std; const int Max_value=1000; ifstream fin("knapsack.in"); ofstream fout("knapsack.out"); int main() { int t,m,i,j,l; int *weight,*v,**f; fin>>t>>m; //get the max volum,and the goods number. /* new array ,according as the given number*/ weight = new int[m+1]; memset(weight,0,m+1); v = new int[m+1]; f=new int*[m+1]; for(i=0;i<m+1;i++) { f[i]=new int[Max_value]; memset(f[i],0,Max_value); } // fout<<"sizeof:"<<sizeof(weight)<<endl; //read test cases fout<<t<<" "<<m<<endl; for(i=1;i<=m;i++) fin>>weight[i]>>v[i]; fout<<weight[i]<<" "<<v[i]<<endl; //Dynamic programming ,according to translation function for(j=1;j<=t;j++) if (weight[i]<=j && (l=f[i-1][j-weight[i]]+v[i])>f[i-1][j]) f[i][j]=l; else f[i][j]=f[i-1][j]; fout<<"The max velue:"<<f [t]; delete weight,v; for(int i=0;i<m+1;i++) delete f[i]; delete f; return 0; } 以上只是一个简单的说明事例,具体的动态规划问题,需要具体分析,得出状态转换方程,并依据方程修改程序。 |
#include <fstream>
#include <iostream>
using namespace std;
const int Max_value=1000;
ifstream fin("knapsack.in");
ofstream fout("knapsack.out");
int main()
{
int t,goodnum,i,j,l;
int *weight,*value,**f;
fin >> t >> goodnum; // t=10 and m=3 //get the max volum,and the goods number.
/* new array ,according as the given number*/
weight = new int[goodnum+1];//动态生成一个数组,存放物品的重量
memset(weight,0,goodnum+1);//设置为零
value = new int[goodnum+1];//申请一个一维数组,存放物品的价值
memset(weight,0,goodnum+1);//初始化为零
f=new int*[goodnum+1]; //f 指向 int*
for(i=0;i<goodnum+1;i++)//二维数组初始化
{
f[i]=new int[Max_value];
memset(f[i],0,Max_value);
}
// fout<<"sizeof:"<<sizeof(weight)<<endl;