该题第一思路就是直接根据所给条件写出各种情况下的递归即可,但是题目实际上暗示了,该题并不能这样做,会超时,因此我们尝试使用记忆化搜索进行优化,通过观察我们不难发现,在输入的a,b,c中实际上最大计算不会超过w(20,20,20),并且如果存在负数的话,就直接返回1,因此我们的记忆数组并不需要开太大
#include<iostream> #define ll long long using namespace std; const int MAX=30; ll s[MAX][MAX][MAX];//用来存储已经计算过的值 ll fun(ll a,ll b,ll c){ if(a<=0||b<=0||c<=0){ return 1; }else if(a>20||b>20||c>20){ return fun(20,20,20);//这里也不能存储s[a][b][c]也可能a,b,c太大导致越界 }else if(s[a][b][c]){//注意这里的记忆判断不能放在第一行,因为存在输入为负数,会导致越界 return s[a][b][c]; }else if(a<b&&b<c){ return s[a][b][c]=fun(a,b,c-1)+fun(a,b-1,c-1)-fun(a,b-1,c); }else{ return s[a][b][c]=fun(a-1,b,c)+fun(a-1,b-1,c)+fun(a-1,b,c-1)-fun(a-1,b-1,c-1); } } int main(){ ll a,b,c; while(cin>>a>>b>>c){ if(a==-1&&b==-1&&c==-1)break; cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<fun(a,b,c)<<endl; } return 0; }
Function(记忆化搜索)
最新推荐文章于 2024-06-05 21:38:06 发布