当前位置: 代码迷 >> 综合 >> A decorative fence
  详细解决方案

A decorative fence

热度:56   发布时间:2023-12-21 05:13:15.0

http://acm.pku.edu.cn/JudgeOnline/problem?id=1037  A decorative fence,这是一道递推的好题啊!

具体的我也不说了,去看解题报告吧。

发现子问题是一个难点,而且进一步的处理也是比较烦的,最好想清楚了再写,不然……

而且输出也很别致。

 

#include  < iostream >
#include 
< iterator >
using   namespace  std;

const   int  N = 21 ; //  N
const   int  M = 21 ; // j
/*

up[i][j]=down[i][i+1-j];
down[i][j+1]=down[i][j]+up[i-1][j]
*/

__int64 down[N][M]
= { 0 },up[N][M];

void  solve( int  n)
{
    
int  i,j;
    down[
2 ][ 2 =  up[ 1 ][ 1 =   1 ;
    
for  (i = 2 ; i <= n; i ++ )
    {
        
for  (j = 1 ; j < i; j ++ )
            down[i][j
+ 1 =  down[i][j]  +  up[i - 1 ][j];
        
for  (j = 1 ; j <= i; j ++ )
            up[i][j] 
=  down[i][i + 1 - j];
    }
}


int  iV[N];
void  goUp( int ,__int64, int );
void  goDown( int  n,__int64 c, int  lowerBound)
{
    
if  (n == 1 )    {cout << iV[n] << '   ' ;     return ;    }
    
int  i,j;
    
for  (i = lowerBound;i <= n;i ++ )
    {
        c
-= down[n][i];
        
if  (c < 1 )
        {
            cout
<< iV[i] << '   ' ;
            
for  (j = i;j <= n;j ++ )
                iV[j]
= iV[j + 1 ];
            goUp(n
- 1 ,c + down[n][i],i - 1 ); // upperbound not neccessary
             break ;
        }
    }
}

void  goUp( int  n,__int64 c, int  upperBound)
{
    
if  (n == 1 )
    {
        cout
<< iV[n] << '   ' ;
        
return  ;
    }
    
int  i,j;
    
for  (i = 1 ;i <= upperBound;i ++ )
    {
        c
-= up[n][i];
        
if  (c < 1 )
        {
            cout
<< iV[i] << '   ' ;
            
for  (j = i;j < n;j ++ )
                iV[j]
= iV[j + 1 ];
            goDown(n
- 1 ,c + up[n][i],i);
            
break ;
        }
    }
}

void  output( int  n,__int64 c)
{
    
int  i,j;
    
for  (i = 1 ;i <= n;i ++ )
        iV[i]
= i;
    
if  (n == 1 )
    {
        cout
<< iV[n] << '   ' ;
    }
    
for  (i = 2 ;i <= n;i ++ )
    {
        c
-= up[n][i - 1 ];
        
if  (c < 1 )
        {
            cout
<< iV[i - 1 ] << '   ' ;
            
for  (j = i - 1 ;j < n;j ++ )
                iV[j]
= iV[j + 1 ];
            goDown(n
- 1 ,c + up[n][i - 1 ],i - 1 );
            
break ;
        }
        c
-= down[n][i];
        
if  (c < 1 )
        {
            cout
<< iV[i] << '   ' ;
            
for  (j = i;j < n;j ++ )
                iV[j]
= iV[j + 1 ];
            goUp(n
- 1 ,c + down[n][i],i);
            
break ;
        }
        
    }
}    

int  main()
{
    
int  nCase,n;
    __int64 c;
    solve(N
- 1 );
    cin
>> nCase;
    
while  (nCase -- )
    {
        cin
>> n >> c;
        output(n,c);
        cout
<< endl;
        
/* solve(n,c); */
    }
    
return   0 ;
}