题目描述
对于一个递归函数w(a,b,c)w(a,b,c)
- 如果a≤0 or b≤0 or c≤0就返回值11.
- 如果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−1,−1,−1结束。
保证输入的数在[-9223372036854775808,9223372036854775807]之间,并且是整数。
输出格式
输出若干行,每一行格式:
w(a, b, c) = ans
注意空格。
输入输出样例
输入 #1复制
1 1 1
2 2 2
-1 -1 -1
输出 #1复制
w(1, 1, 1) = 2
w(2, 2, 2) = 4
说明/提示
记忆化搜索
解答:(因为直接用DP+记忆化就好,思路比较简单,直接代码)
/*思路:记忆化*/
#include <cstdio>
typedef long long LL;
const int MAX = 21*21*21;
/*MAX = 20*20*20 error_1:这是我之前的写法,错误点在于,abc <= 20,则应当用21 进制才行*/
int mems[MAX]; //memorys
bool flags[MAX];
int get_index(int a,int b,int c) //对 a,b,c hash
{ return a*21*21 + b*21 + c; }
int w(int a,int b,int c){
//设置出口
if(a <= 0||b <= 0||c <= 0) return 1;
//记忆化
int index = get_index(a,b,c);
if(flags[index]) return mems[index];
//递归过程
if(a < b&&b < c)
mems[index] = w(a,b,c-1) + w(a,b-1,c-1) - w(a,b-1,c);
else
mems[index] = w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
flags[index] = true;
return mems[index];
}
int main()
{
LL a,b,c;
int ans;
while(scanf("%lld %lld %lld",&a,&b,&c)){
if(a == -1&&b == -1&&c == -1) break;
else if(a <= 0||b <= 0||c <= 0) ans = 1;
/*error2:我没写这条语句。题目要求同时满足条件1、2时,所以在判断2前要先判断1。因为读入的abc可能是long long型,而真正用到的其实是小于21的数,所以我为了函数传参时可以传int型将判断2的语句提了出来,之后才导致忘了在其之前+判断1的语句。*/
/*error3:此处还发生了一个错误就是,多出了一个判断,而之前我的输出语句是写在else下的,多了这个条件之后,当这条判断成功时不会输出内容了。*/
else{
if(a > 20||b > 20||c > 20)
ans = w(20,20,20);
else
ans = w(a,b,c);
}
printf("w(%lld, %lld, %lld) = %d\n",a,b,c,ans);
/*error4:同error3,自己将输出语句写在了else内(因为当时if中直接break了,所以觉得写在else里没问题),导致多出一个判断的时候存在有的情况没有输出。*/
}
return 0;
}
总结:(针对犯得错误)
总的说来,犯得错误分为两种,一种是读题不清,另一种是代码问题,下面说说解决办法。
读题不清:
首先第一遍读题肯定不可能什么时候都面面俱到,因为还是要以完成功能为前提。但是可以在完成要求的同时针对题目的一个一个要求多考察细节,所以解决办法分两步。
第一步:对于有些难度的题,多用函数将各功能分离,因为题目的要求也是一步步来的,针对每个函数去对应地仔细看题目要求。
第二部:在完成之后,要大致再对应题目看一遍,不能只依赖样例,这样总是会形成以样例为标准而忽略题目要求。
代码问题:
代码问题中又有两个问题,一是自己的代码洁癖,二是对题目要求是否彻底落实。
代码洁癖的问题要引起自己的重视,自己总是为了避免重复代码和为了机器节省空间和操作,总是想把代码写的很简洁,但这样有时会太可以使得自己忽略了本身要实现的功能,所以以后先用自己最有把握实现问题的方式写,当完全通过之后再试着将刚才想改进的地方改进,这样慢慢熟悉了简单的写法之后再在做题中使用。
对题目是否落实的问题其实在解决了代码洁癖的问题和读题不清的问题之后其实就解决了十之八九了。