地址:http://acm.hdu.edu.cn/showproblem.php?pid=1297
题意:n个字母,由F和M组成。F不能单独存在。求满足条件的字符串数目。
mark:递推很容易得到方程dp[n] = 2*dp[n-1]-dp[n-2]+dp[n-3]。但是题目中n最大是1000,结果是200多位的整数,要写成大数运算,大数减法没写过。。。方程可等价为dp[n] = dp[n-1]+dp[n-2]+dp[n-4],这样就回避了减法的问题。
代码:
# include <stdio.h>
# include <string.h>
char ans[1010][300] ;
int anum[300], bnum[300] ;
int c[300] ;
void strtonum(int num[], char s[])
{
int i ;
num[0] = strlen(s) ;
for (i = num[0] - 1 ; i>= 0 ; i--)
num[num[0]-i] = s[i]-'0' ;
}
void numtostr(char s[], int num[])
{
int i ;
s[num[0]] = '\0' ;
for (i = 1 ; i <= num[0] ; i++)
s[num[0]-i] = num[i]+'0' ;
}
void numadd(int a[], int b[])
{
int cc = 0 ;
int *p, *q, i ;
if (a[0] < b[0]) p = a, q = b ;
else p = b, q = a ;
for (i = 1 ; i <= q[0] ; i++)
{
if (i <= p[0])
c[i] = p[i]+q[i]+cc ;
else c[i] = q[i]+cc ;
cc = c[i] /10 ;
c[i] %= 10 ;
}
if (cc != 0) c[i++] = cc ;
c[0] = i-1 ;
for (i = 0 ; i <= c[0] ; i++)
a[i] = c[i] ;
}
void add(char a[], char b[])
{
strtonum(anum, a) ;
strtonum(bnum, b) ;
numadd(anum,bnum) ;
numtostr(a, anum) ;
}
int init()
{
int i ;
strcpy(ans[0], "1") ;
strcpy(ans[1], "1") ;
strcpy(ans[2], "2") ;
strcpy(ans[3], "4") ;
for(i = 4 ; i <= 1000 ; i++)
{
strcpy(ans[i], "0") ;
add(ans[i], ans[i-1]) ;
add(ans[i], ans[i-2]) ;
add(ans[i], ans[i-4]) ;
}
}
int main ()
{
int n ;
init() ;
while (~scanf ("%d", &n))
puts (ans[n]) ;
return 0 ;
}