以数据结构,算法与应用中第15章为材料
1.先是没有储存中间结果的递归解法(即这种方法没有用到动态规划,就是普通的递归解法)。统计结果+递归次数+运行时间。程序如下:
int F(int i, int y, int n, int *weight, int *value); // 0/1背包问题
static int count_recursive = 0; //用于调试,统计递归调用次数
int main()
{
clock_t clockbegin,clockend;
clockbegin = clock();
/*int weight[] = {100, 14, 10};
int value[] = {20, 18, 15};
int n = 3, capacity = 116;*/
int weight[] = {2,2,6,5,4};
int value[] = {6,3,5,4,6};
int n = 5, capacity = 10;
int result = F(0,capacity, n, weight, value);
clockend = clock();
cout << clockend-clockbegin << "ms" << endl;
cout << "recursive " << count_recursive << " times" << endl;
cout << result<< endl;
system("pause");
return 0;
}
int F(int i, int y, int n, int *weight, int *value)
{
++count_recursive; 用于调试,统计递归调用次数
int result;
if(i == n-1)
{
result = (y>=weight[n-1])? value[n-1]:0;
return result;
}
if(y<weight[i])
result = F(i+1, y, n, weight, value);
else
result = ( F(i+1,y, n, weight, value)>F(i+1, y-weight[i], n, weight, value)+value[i] ? F(i+1,y, n, weight, value): F(i+1, y-weight[i], n, weight, value)+value[i]);
return result;
}
在进入“动态规划之前”,先看下这个普通递归的运行结果:
最不对劲的地方是递归进行了99次,而“数据结构,算法与应用”则是进行了28次。
——》有个问题应该出在条件表达式那里:
result = ( F(i+1,y, n, weight, value)>F(i+1, y-weight[i], n, weight, value)+value[i] ? F(i+1,y, n, weight, value): F(i+1, y-weight[i], n, weight, value)+value[i]);
经跟踪调试:
1——》这个语句会先运行F(i+1,y, n, weight, value)>F(i+1, y-weight[i], n, weight, value)部分,这里将有2次直接的调用函数,并且如果每个函数调用没有到直接返回的条件还将进行下一步的递归调用;
2——》执行完这个“>”表达式后,将选择两者其中之一又求值一次,例如F(i+1,y, n, weight, value)较大的话,则又将对F(i+1,y, n, weight, value): F(i+1, y-weight[i], n, weight, value)+value[i])的前半部分再次求值,这会带来一次直接的函数调用+内部可能存在的进一步的递归调用
改变这个地方后,程序变为
int result1 = F(i+1,y, n, weight, value);
int result2 = F(i+1, y-weight[i], n, weight, value)+value[i];
result = ( result1>result2 ? result1: result2);
运行结果为
比书上的递归少了一次(有待继续跟踪)