华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1143|回复: 2
打印 上一主题 下一主题

P1464 Function

[复制链接]

2

主题

19

帖子

114

积分

注册会员

Rank: 2

积分
114
跳转到指定楼层
楼主
发表于 2019-11-1 20:55:40 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
https://www.luogu.org/problem/P1464

题目描述:对于一个递归函数w(a,b,c)
如果a≤0 or b≤0 or c≤0就返回值1.
如果a>20 or b>20 or 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时,调用的次数将非常的多。你要想个办法才行.

/* absi2011 : 比如 w(30,−1,0)既满足条件1又满足条件2

这种时候我们就按最上面的条件来算

所以答案为1

*/

输入格式
会有若干行。

并以-1,-1,-1结束。

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

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

w(a, b, c) = ans

注意空格。

输入输出样例
输入
1 1 1
2 2 2
-1 -1 -1
输出
w(1, 1, 1) = 2
w(2, 2, 2) = 4
说明/提示
记忆化搜索
回复

使用道具 举报

0

主题

5

帖子

188

积分

注册会员

Rank: 2

积分
188
板凳
发表于 2019-11-4 13:03:22 | 只看该作者
  1. #include<iostream>
  2. using namespace std;
  3. #define ll long long
  4. ll s[25][25][25];
  5. ll w(ll a,ll b,ll c)
  6. {
  7.     if((a<0||a==0)||(b<0||b==0)||(c<=0||c==0)) return 1;
  8.     if(a>20||b>20||c>20) return w(20,20,20);
  9.     if(s[a][b][c]!=0) return s[a][b][c];
  10.     if(a<b && b<c){
  11.          s[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
  12.         return s[a][b][c];
  13.     }
  14.     else{
  15.      s[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);
  16.     return s[a][b][c];
  17.     }
  18. }
  19. int main()
  20. {
  21.    ll a,b,c;
  22.    while(true)
  23.    {
  24.        cin>>a>>b>>c;
  25.        if(a==-1&&b==-1&&c==-1) return 0;
  26.        cout<<'w'<<'('<<a<<", "<<b<<", "<<c<<") = "<<w(a,b,c)<<endl;
  27.    }
  28. }
复制代码
回复 支持 反对

使用道具 举报

2

主题

19

帖子

114

积分

注册会员

Rank: 2

积分
114
沙发
 楼主| 发表于 2019-11-1 20:59:07 | 只看该作者
  1. #include<stdio.h>
  2. int f[21][21][21];
  3. int aa[10000],bb[10000],cc[10000];
  4. int w(int a,int b,int c)
  5. {
  6. if(a<=0||b<=0||c<=0) return 1;
  7. if(a>20||b>20||c>20) return w(20,20,20);
  8. if(f[a][b][c] != f[0][0][0]) return f[a][b][c];
  9. if(a<b&&b<c) f[a][b][c] = w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);
  10. else f[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);
  11. return f[a][b][c];
  12. }
  13. int main(){
  14.     int a,b,c,i,ii;
  15.     i=0;
  16.     while(a!=-1||b!=-1||c!=-1){
  17.         scanf("%d %d %d",&a,&b,&c);
  18.         aa[i]=a;bb[i]=b;cc[i]=c;
  19.         i++;
  20.     }
  21.     for(ii=0;ii<i-2;ii++){printf("w(%d, %d, %d) = %d \n",aa[ii],bb[ii],cc[ii],w(aa[ii],bb[ii],cc[ii]));}
  22.     printf("w(%d, %d, %d) = %d",aa[ii],bb[ii],cc[ii],w(aa[ii],bb[ii],cc[ii]));
  23.     return 0;
  24. }
复制代码

菜鸡做法
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 14:11 , Processed in 0.144137 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表