在暴力搜索基础上,增加了记忆机制而减少了时间复杂度,动态规划是一种以空间换时间的快速算法。
经典例题:
找零钱问题:用n种货币,组成aim的钱数,有多少种方法;
法一:
初始化一个二维数组dp[n][aim],行数为n,列数为aim。dp[i][j]含义为用penny[0...i]的货币组成j的钱数有多少种方法。
递归公式:
dp[i][j]=dp[i][i-penny[i]]+dp[i-1][j];
//该方法比较通俗易懂。
int countways(vector<int>penny,int n,int aim)
{
//penny存储钱的种类;
int dp[n][aim];
for(int i=0;i<n+1;i++)
{
dp[i][0]=1;
}
for(int i=o;i<aim;i++)
{
if(i%penny[0]==0)
dp[0][i]=1;
else
dp[0][i]=0;
}
for(int i =0;i<n;i++)
{
for(int j=0;j<aim;j++)
{
if(j>=penny[j])
dp[i][j]=dp[i][j-penny[j]]+dp[i-1][j];
else
dp[i][j]=dp[i-1][j];
}
}
return dp[n-1][aim];
}
法二: 有些晦涩
int countways(vector<int>penny,int n,int aim)
{
int f[1000];
memset(f,0,sizeof(f));//memset用于数组清零,从f开始的sizeof(f)长度设置为0;
f[0]=1;
for(int i=0;i<n;i++)
{
for(int j =penny[i];j<=aim;j++)
f[j]+=f[j-penny[i]];
}
return f[aim];
}