zoj 2711 Get Out of the Glass

/*
zoj_2771    dp+高精度
简单dp,不过又是要结合上高精度。。

思路: 对玻璃四层(即四个交接面)分别标记为0,1,2,3
      dp[i][j] 表示第j个反射点在第i层的可能数。
      则易知:
        j%2==0时有: dp[i][j]=sum( dp[k][j-1] ); i<k<4
              否则: dp[i][j]=sum( dp[k][j-1] ); 0=<k<i
*/
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
int dp[4][61][21];

void print( int n )
{
    int i,j,y;
    int sum[21]={0};
    for( i=0;i<4;i++ )    //sum+=dp[i][n]
    {
        y=0;
        for( j=20;j>=0;j-- )
        {
            sum[j]+=( dp[i][n][j]+y );
            y=sum[j]/10000;
            sum[j]%=10000;
        }
    }
    for( i=0;i<21;i++ )
        if( sum[i]!=0 )
        {
            cout<<sum[i];   i++;
            break;
        }
    for( ;i<21;i++ )
    {
        if( sum[i]<1000 ) cout<<'0';
        if( sum[i]<100 )  cout<<'0';
        if( sum[i]<10 )   cout<<'0';
        cout<<sum[i];
    }
    cout<<endl;
}

int main()
{
    int n,i,j,k,l,y;
    memset( dp,0,sizeof(dp) );
    for( i=1;i<4;i++ )  dp[i][1][20]=1;
    for( j=2;j<61;j++ )
    {
        for( i=0;i<4;i++ )
        {
            if( j%2==0 )
                for( k=i+1;k<4;k++ ) //dp[i][j]+=dp[k][j-1]
                {
                    y=0;
                    for( l=20;l>=0;l-- )
                    {
                        dp[i][j][l]+=( dp[k][j-1][l]+y );
                        y=dp[i][j][l]/10000;
                        dp[i][j][l]%=10000;
                    }
                }
            else
                for( k=0;k<i;k++ ) //dp[i][j]+=dp[k][j-1]
                {
                    y=0;
                    for( l=20;l>=0;l-- )
                    {
                        dp[i][j][l]+=( dp[k][j-1][l]+y );
                        y=dp[i][j][l]/10000;
                        dp[i][j][l]%=10000;
                    }
                }
        }
    }
    while( cin>>n )
    {
        if( n==0 )  cout<<"1\n";
        else print(n);
    }
    return 0;
}

你可能感兴趣的:(zoj 2711 Get Out of the Glass)