ZOJ 1346 Comparing Your Heroes

AndyZh說過:

“我們想求一堆人的排列總數,它等於在這一堆人中 減去 每一個 入度爲 0 的人,剩下的人的排列總數的和。具體實現也藉助了回溯法。

如果只剩下一個人,那麼排列總數爲1,這是遞歸的邊界。 ”

 

#include <cstdio>
#include 
<string>
#include 
<map>
using namespace std;

int M, N, a[16][16];
char name[16][100];
double val[65536];        // 位操作
int power[16];            // 求每一位是否存在
int in[16];                // 入度

int init ()
{
    
if ( scanf ( "%d"&N ) == EOF )
        
return 0;
    
int i, j;
    
char x[100], y[100];
    memset ( a, 
0sizeof ( a ) );
    M 
= 0;
    
for ( i = 0; i < N; i ++ )
    
{
        scanf ( 
"%s%s", x, y );
        
int u = -1, v = -1;
        
for ( j = 0; j < M; j ++ )
        
{
            
if ( !strcmp ( name[j], x ) )
                u 
= j;
            
if ( !strcmp ( name[j], y ) )
                v 
= j;
        }

        
if ( u == -1 )
        
{
            strcpy ( name[M], x );
            u 
= M ++;
        }

        
if ( v == -1 )
        
{
            strcpy ( name[M], y );
            v 
= M ++;
        }

        
if ( u != v )
            a[u][v] 
= 1;
    }


    memset ( 
in0x00sizeof ( in ) );
    
for ( i = 0; i < M; i ++ )
        
for ( j = 0; j < M; j ++ )
        
{
            
if ( a[i][j] )
                
in[j] ++;
        }

    
return N;
}


double getValue ( int x )
{
    
if ( val[x] >= 0 )
        
return val[x];
    
int i, j;
    val[x] 
= 0;
    
for ( i = 0; i < M; i ++ )
    
{
        
// 當入度爲0時可以提取在隊列最前方
        if ( !in[i] && ( ( x & power[i] ) == power[i] ) )
        
{
            
for ( j = 0; j < M; j ++ )
            
{
                
if ( a[i][j] )
                    
in[j] --;
            }

            val[x] 
+= getValue ( x ^ power[i] );
            
for ( j = 0; j < M; j ++ )
            
{
                
if ( a[i][j] )
                    
in[j] ++;
            }

        }

    }

    
return val[x];
}


void dp ()
{
    memset ( val, 
0xffsizeof ( val ) );
    
int i;
    
for ( i = 0; i < M; i ++ )
        power[i] 
= 1 << i;
    
for ( i = 0; i < M; i ++ )
        val[power[i]] 
= 1;
    
int x = ( 1 << M ) - 1;
    val[x] 
= getValue ( x );
    printf ( 
"%.0f ", val[x] );
    
//pt ();
}


int main ()
{
    
//freopen ( "in.txt", "r", stdin );
    
//freopen ( "out.txt", "w", stdout );
    while ( init () )
    
{
        dp ();
    }

    
return 0;
}
發佈了56 篇原創文章 · 獲贊 0 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章