测评地址:https://www.luogu.org/problemnew/show/P1464
本题采用记忆化搜索。
百度百科:一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态。更重要的是搜索还可以剪枝,可能剪去大量不必要的状态,因此在空间开销上往往比动态规划要低很多。记忆化算法在求解的时候还是按着自顶向下的顺序,但是 每求解一个状态,就将它的解保存下来 ,以后再次遇到这个状态的时候,就不必重新求解了。这种方法综合了搜索和动态规划两方面的优点,因而还是很有实用价值的。
下面上AC代码:
#include<iostream>
#include<cstdio>
using namespace std;
long long arr[25][25][25];//long long防止数据过大
long long w(long long a,long long b,long long c)
{
if(a<=0 or b<=0 or c<=0) return 1;
else if(a>20 or b>20 or c>20) return 1048576;
else if(arr[a][b][c]!=0) return arr[a][b][c];
else if(a<b and b<c) arr[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
else arr[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);
return arr[a][b][c];
}
int main()
{
long long a,b,c;
while(true)
{
scanf("%lld%lld%lld",&a,&b,&c);
if(a==-1 and b==-1 and c==-1) break;
else printf("w(%lld, %lld, %lld) = %lld\n",a,b,c,w(a,b,c));
}
return 0;
}