题目大意:求一个递归函数w(a,b,c)的值.w(a,b,c)如下定义:
若a <= 0 或 b <= 0 或 c <= 0, 那么 w(a, b, c)=1
若 a > 20 或 b > 20 或 c > 20, 那么 w(a, b, c)=w(20, 20, 20)
若a < b 且 b < c, 那么 w(a, b, c)=w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
若a <= 0 或 b <= 0 或 c <= 0, 那么 w(a, b, c)=1
若 a > 20 或 b > 20 或 c > 20, 那么 w(a, b, c)=w(20, 20, 20)
若a < b 且 b < c, 那么 w(a, b, c)=w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)
对其余情况,w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)
思路:一道记忆化搜索的水题,通过这道题可以更好的理解记忆化搜索。其实就是搜索的形式+动态规划的思想。动态规划需要遍历所有的状态,而搜索可以排除一些无效状态。记忆化搜索在求解的时候还是自顶向下,但是每求解一个状态,就将它的解保存下来,以后再次遇到这个状态的时候,就可以直接获取而不用重新求解了。
#include <stdio.h>
#include <memory.h>
int dp[24][24][24];
int w( int a, int b, int c ) {
if (a<=0||b<=0||c<=0)
return 1;
if (a>20||b>20||c>20)
return dp[20][20][20]=w(20,20,20);
if (a<b&&b<c) {
if (dp[a][b][c]!=0)
return dp[a][b][c];
else {
return dp[a][b][c]=w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c);
}
}
else {
if (dp[a][b][c]!=0)
return dp[a][b][c];
else
return dp[a][b][c]=w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1);
}
}
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
memset(dp,0,sizeof(dp));
while (!(a==-1&&b==-1&&c==-1)) {
printf("w(%d, %d, %d) = %d\n",a,b,c,w(a,b,c));
scanf("%d%d%d",&a,&b,&c);
}
return 0;
}