《算法竞赛入门经典》P158
第一个例题是数塔,比较好理解,不过如果不是之前做过这道题的话估计还是会很纠结。
一开始的方法貌似可以叫穷举,会造成重复计算,效率低;
之后加入记忆,避免了重复计算。
大概试着写出来对比了下,记录:
#include<iostream>
#include<cstring>
using namespace std;
int a[10][10],m[10][10];
int n=5;
int call_num=1;
int max_sum(int i,int j)
{
cout<<"aaaa "<<call_num<<endl;
++call_num;
if(i==n)
{
return a[i][j];
}
else
{
if(m[i][j]==0)
{
int x=max_sum(i+1,j);
int y=max_sum(i+1,j+1);
m[i][j]=a[i][j]+(x>y ? x:y);
}
return m[i][j];
}
}
int max_sum_2(int i,int j)
{
cout<<"aaaa "<<call_num<<endl;
++call_num;
if(i==n)
{
return a[i][j];
}
else
{
int x=max_sum_2(i+1,j);
int y=max_sum_2(i+1,j+1);
return a[i][j]+(x>y ? x:y);
}
}
int main()
{
memset(a,0,sizeof(a));
memset(m,0,sizeof(m));
/*
a[1][1]=3;
a[2][1]=6; a[2][2]=8;
a[3][1]=5; a[3][2]=9; a[3][3]=7;
a[4][1]=13; a[4][2]=2; a[4][3]=3; a[4][4]=3;
*/
a[1][1]=1;
a[2][1]=3; a[2][2]=2;
a[3][1]=4; a[3][2]=10; a[3][3]=1;
a[4][1]=4; a[4][2]=3; a[4][3]=2; a[4][4]=20;
a[5][1]=7; a[5][2]=3; a[5][3]=6; a[5][4]=4; a[5][5]=1;
cout<<max_sum(1,1)<<endl;
}
max_sum和max_sum_2分别是使用了记忆与没使用的,通过call_num的大小比较两种方法的次数
结果分别是21,28和31,28
而且差异随行数增加