【洛谷P1464】Function

Function

题目描述

对于一个递归函数 \(w(a,b,c)\)

  • 如果 \(a \le 0\)\(b \le 0\)\(c \le 0\) 就返回值 \(1\)
  • 如果 \(a>20\)\(b>20\)\(c>20\) 就返回 \(w(20,20,20)\)
  • 如果 \(a<b\) 并且 \(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)\)

这是个简单的递归函数,但实现起来可能会有些问题。当 \(a,b,c\) 均为 \(15\) 时,调用的次数将非常的多。你要想个办法才行。

注意:例如 \(w(30,-1,0)\) 又满足条件 \(1\) 又满足条件 \(2\),请按照最上面的条件来算,答案为 \(1\)

输入格式

会有若干行。

并以 \(-1,-1,-1\) 结束。

输出格式

输出若干行,每一行格式:

w(a, b, c) = ans

注意空格。

样例 #1

样例输入 #1

1 1 1
2 2 2
-1 -1 -1

样例输出 #1

w(1, 1, 1) = 2
w(2, 2, 2) = 4

提示

数据规模与约定

保证输入的数在 \([-9223372036854775808,9223372036854775807]\) 之间,并且是整数。

保证不包括 \(-1, -1, -1\) 的输入行数 \(T\) 满足 \(1 \leq T \leq 10 ^ 5\)

解法

首先我们看到这题所属的题单 是递归和递推
而这题是典型的递归题型 因此看到这个离谱的数据
我们会想到以空间换时间
也就是所谓的记忆化搜索
这题基本上算记忆化的入门题了
下面看代码吧

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,b,c;
ll f[25][25][25];
ll w(ll a,ll b,ll c){
    if(a<=0||b<=0||c<=0) return 1;
    else if(a>20||b>20||c>20) return w(20,20,20);
    else if(a<b&&b<c){
        if(f[a][b][c-1]==0) f[a][b][c-1]=w(a,b,c-1);
        if(f[a][b-1][c-1]==0) f[a][b-1][c-1]=w(a,b-1,c-1);
        if(f[a][b-1][c]==0) f[a][b-1][c]=w(a,b-1,c);
        f[a][b][c]=f[a][b][c-1]+f[a][b-1][c-1]-f[a][b-1][c];
    }
    else{
        if(f[a-1][b][c]==0) f[a-1][b][c]=w(a-1,b,c);
        if(f[a-1][b-1][c]==0) f[a-1][b-1][c]=w(a-1,b-1,c);
        if(f[a-1][b][c-1]==0) f[a-1][b][c-1]=w(a-1,b,c-1);
        if(f[a-1][b-1][c-1]==0) f[a-1][b-1][c-1]=w(a-1,b-1,c-1);
        f[a][b][c]=f[a-1][b][c]+f[a-1][b-1][c]+f[a-1][b][c-1]-f[a-1][b-1][c-1];
    }
    return f[a][b][c];
}
int main(){
    while(cin>>a>>b>>c){
        if(a==-1&&b==-1&&c==-1) break;
        cout<<'w'<<'('<<a<<','<<' '<<b<<','<<' '<<c<<')'<<' '<<'='<<' '<<w(a,b,c);
        cout<<endl; 
    }
    system("pause");
    return 0;
}

  

posted @ 2025-01-29 23:03  Elainafan  阅读(21)  评论(1编辑  收藏  举报