BZOJ 1087: [SCOI2005]互不侵犯King( 狀壓dp )

來源:互聯網
上載者:User

標籤:

簡單的狀壓dp...

dp( x , h , s ) 表示當前第 x 行 , 用了 h 個 king , 當前行的狀態為 s .

考慮轉移 : dp( x , h , s ) = ∑ dp( x - 1 , h - cnt_1( s ) , s‘ ) ( s and s‘ 兩行不衝突 , cnt_1( s ) 表示 s 狀態用了多少個 king )

我有各種預先處理所以 code 的方程和這有點不一樣

----------------------------------------------------------------------------------

#include<cstdio>

#include<cstdlib>#include<cstring>#include<algorithm>#include<vector>#include<iostream> #define clr( x , c ) memset( x , c , sizeof( x ) )#define rep( i , n ) for( int i = 0 ; i < n ; ++i )#define b( i ) ( 1 << ( i ) ) using namespace std; typedef long long ll;const int maxn = 10;const int maxstate = 100; vector< int > state;vector< int > cnt;vector< int > ok[ maxstate ];int n , k;ll d[ maxn ][ maxn * maxn ][ maxstate ]; void init() {state.clear() , cnt.clear();clr( d , -1 );clr( d[ 0 ] , 0 );cin >> n >> k;rep( s , b( n ) ) if( ! ( s & ( s << 1 ) ) ) {state.push_back( s );int t = 0;    for( int h = s ; h ; h >>= 1 ) t += h & 1;    cnt.push_back( t );    d[ 0 ][ t ][ state.size() - 1 ] = 1;}rep( i , state.size() )     ok[ i ].clear();rep( i , state.size() )for( int j = i ; j < state.size() ; j++ )    if( ! ( state[ j ] & state[ i ] ) && ! ( ( state[ j ] << 1 ) & state[ i ] ) && ! ( ( state[ i ] << 1 ) & state[ j ] ) ) {        ok[ i ].push_back( j );        if( i != j ) ok[ j ].push_back( i );    }} ll dp( int x , int h , int t ) {if( h < 0 ) return 0;ll &ans = d[ x ][ h ][ t ];if( ans != -1 ) return ans;ans = 0;if( h < cnt[ t ] ) return ans;for( vector< int > :: iterator it = ok[ t ].begin() ; it != ok[ t ].end() ; it++ )    ans += dp( x - 1 , h - cnt[ t ] , *it );return ans;} void work() {ll ans = 0;    rep( i , state.size() )     ans += dp( n - 1 , k , i );cout << ans << "\n";} int main() {//freopen( "test.in" , "r" , stdin );//freopen( "test.out", "w", stdout );init();work();    return 0; } 

---------------------------------------------------------------------------------- 

 

1087: [SCOI2005]互不侵犯KingTime Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1974  Solved: 1171
[Submit][Status][Discuss]Description

在N×N的棋盤裡面放K個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各一個格子,共8個格子。

Input

只有一行,包含兩個數N,K ( 1 <=N <=9, 0 <= K <= N * N)

Output

方案數。

Sample Input3 2Sample Output16HINT

Source

 

BZOJ 1087: [SCOI2005]互不侵犯King( 狀壓dp )

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.