HDU2047 阿牛的EOF牛肉串 递推 C语言

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2047 

开心~~第一次完全自己做出来的递推~~虽然想的过程有些纠结,但是规律毕竟是找出来了。
 
思路:
f[i]表示长度为i时的方案数, o[i]表示长度为i时所有方案中末位字母是o的个数.
1)当长度n = 1时,有三种涂法 : E、 O、 F. f[1] = 1.其中O的个数为1, o[1] = 1.
2)当长度n = 2时,E、 F分别又对应出3种情况(E、O、F), O对应出两种情况(E、F),因为不能有OO出现.末位O的个数o[2] = 2.
f[2] = 3 * f[1] - 1 = 3 * f[1] - o[1]. o[2] = f[1] - o[1].
3)继续推两组可以看出 :
{
f[i] = 3 * f[i - 1] - o[i - 1] . 因为f[i - 1]中的末位O后不能再加O,所以f[i - 1]中有几个末位O就减去几,即减去o[i - 1] .
o[i] = f[i - 1] - o [i - 1] . 因为f[i - 1]中末位的E、F分别可以对应出一个O, 而O不能对应出一个O,所以f[i - 1]的总方案数减去其中末尾O的个数o[i - 1] 就是f[i - 1] 中末尾为E、F的个数.
}
 
如果还看不懂的话,可以自己画出树状图看对照一下,就很容易看出来了。
提交情况:2次RE , 1次WA , 1次AC
 
AC code:
 
View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3 #define MAXN 40 + 10
4 int main () {
5 int n;
6 __int64 f[MAXN] = {0, 3};
7 __int64 o[MAXN] = {0, 1};
8 int i;
9 for (i = 2; i < MAXN; i++) {
10 f[i] = 3 * f[i - 1] - o[i - 1]; // 每个末位字母又对应出三种情况,要减去OO的情况
11 o[i] = f[i - 1] - o[i - 1]; // f[i]中末位O的个数即是f[i - 1]中末位E、F的个数
12 }
13 while (~scanf ("%d", &n))
14 printf ("%I64d\n", f[n]);
15 //system ("pause");
16 return 0;
17 }
两次RE因为数组下表越界了, 我很白痴的算了f[MAXN]……。 一次WA因为规律推错了,重推一遍就AC了。
注意f[i]和o[i]要开成__int64的,不然会溢出.

posted @ 2011-07-20 13:10  cloehui  阅读(442)  评论(0编辑  收藏  举报