ZOJ 2711 Regular Words

假设F(a,b,c)表示在当前拥有ABC/的数量分别为abc,那么F(a,b,c)=F(a-1,b,c)+F(a,b-1,c)+F(a,b,c-1)。

看上去很简单,实际上的操作有两个难点。

1. F(a,b,c)相当大。采用高精度加法。

2.a的取值范围相当大。只能使用char数组。

 

#include  < cstdio >
#include 
< string >

int  N;
char  f[ 61 ][ 61 ][ 61 ][ 90 ];

void  dp ();
void  print (  int int int  );

int  main ()
{
    
//freopen ( "in.txt", "r", stdin );
    dp ();
    
while ( scanf ( "%d"&N ) == 1 )
    
{
        
//printf ( "%0.0f ", f[N][N][N] );
        print ( N, N, N );
        printf ( 
" " );
    }

    
return 0;
}


void  print (  int  a,  int  b,  int  c )
{
    
int i;
    
for ( i = 89; i >= 0; i -- )
    
{
        
if ( f[a][b][c][i] )
            
break;
    }

    
if ( i == -1 )
        printf ( 
"0 " );
    
else
    
{
        
for ( ; i >= 0; i -- )
            printf ( 
"%d", f[a][b][c][i] );
        printf ( 
" " );
    }

}


void  dp ()
{
    
int a, b, c, l, i, ac = 0;
    memset ( f, 
0sizeof ( f ) );
    f[
1][0][0][0= 1;
    
for ( l = 2; l <= 180; l ++ )
    
{
        
for ( a = 0; a <= l && a <= 60; a ++ )
        
{
            
for ( b = 0; b <= a && b <= 60; b ++ )
            
{
                c 
= l - a - b;
                
if ( c > b )
                    
continue;
                
if ( c < 0 )
                    
break;
                
if ( a > 0 )
                
{
                    
//f[a][b][c] += f[a - 1][b][c];        
                    ac = 0;
                    
for ( i = 0; i < 90; i ++ )
                    
{
                        f[a][b][c][i] 
+= f[a - 1][b][c][i] + ac;
                        
if ( f[a][b][c][i] >= 10 )
                            ac 
= 1, f[a][b][c][i] -= 10;
                        
else 
                            ac 
= 0;
                    }
                    
                }

                
if ( b > 0 )
                
{
                    
//f[a][b][c] += f[a][b - 1][c];    
                    ac = 0;
                    
for ( i = 0; i < 90; i ++ )
                    
{
                        f[a][b][c][i] 
+= f[a][b - 1][c][i] + ac;
                        
if ( f[a][b][c][i] >= 10 )
                            ac 
= 1, f[a][b][c][i] -= 10;
                        
else 
                            ac 
= 0;
                    }

                }

                
if ( c > 0 )
                
{
                    
//f[a][b][c] += f[a][b][c - 1];
                    ac = 0;
                    
for ( i = 0; i < 90; i ++ )
                    
{
                        f[a][b][c][i] 
+= f[a][b][c - 1][i] + ac;
                        
if ( f[a][b][c][i] >= 10 )
                            ac 
= 1, f[a][b][c][i] -= 10;
                        
else
                            ac 
= 0;
                    }

                }

            }

        }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值