zoukankan      html  css  js  c++  java
  • BZOJ 4057: [Cerc2012]Kingdoms( 状压dp )

    状压dp....

    我已开始用递归结果就 TLE 了... 不科学啊...我dp基本上都是用递归的..我只好改成递推 , 刷表法

    将全部公司用二进制表示 , 压成一个数 . 0 表示破产 , 1 表示没破产 . dp( S ) 表示 S 状态是否能够达到 , 能为 1 ( true ) , 不能为 0 ( false ) .

    dp( S ) =  max( dp( S ^ { x } ) , ( S & x == 0 && ∑debt > 0 )

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
     
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define clr( x , c ) memset( x , c , sizeof( x ) )
    #define b( i ) ( 1 << ( i ) )
     
    using namespace std;
     
    const int maxn = 20;
    const int maxs = 1 << maxn;
     
    bool d[ maxs ];
    int debt[ maxn ][ maxn ];
    int n;
     
    void init() {
    clr( d , 0 );
    scanf( "%d" , &n );
    rep( i , n )
       rep( j , n ) scanf( "%d" , &debt[ i ][ j ] );
    d[ b( n ) - 1 ] = true;
    }
     
    void work() {
    int all = b( n ) - 1;
    for( int i = all ; i ; i-- ) if( d[ i ] ) 
       rep( j , n ) if( i & b( j ) ) {
        int cnt = 0;
        rep( k , n ) if( i & b( k ) ) 
           cnt += debt[ j ][ k ];
        if( cnt > 0 ) d[ i ^ b( j ) ] = true;
       }
    bool flag = false;
    rep( i , n ) if( d[ b( i ) ] ) {
    flag ? putchar( ' ' ) : flag = true;
    printf( "%d" , i + 1 );
    }
    if( ! flag ) putchar( '0' );
    putchar( ' ' );
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    freopen( "test.out" , "w" , stdout );
    int t;
    cin >> t;
    while( t-- ) {
       init();
       work();
    }
    return 0;
    }

      

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

    4057: [Cerc2012]Kingdoms

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 203  Solved: 98
    [Submit][Status][Discuss]

    Description

    有一些王国陷入了一系列的经济危机。在很多年以前,他们私底下互相借了许多钱。现在,随着他们的负债被揭发,王国的崩溃不可避免地发生了……现在有n个王国,对于每对王国A和B,A欠B的钱被记为d_AB(我们假设有d_BA=-d_AB成立)。如果一个王国入不敷出(即需要支付超过所能获得的钱),它就可能破产。每当一个王国破产,与它相关的所有债务关系都会被去除,无论是正是负。而王国们的破产不是一瞬间完成的,而是第一个王国破产后,接下来可能破产的王国再继续破产,直到剩下的王国经济都是稳定的。不同的结局将取决于谁先破产,尤其是有的结局只会留下一个王国。请你计算,对于每个王国,是否存在一种结局使得该王国是唯一的幸存者。

    Input

    第一行一个正整数T,表示有T组数据。

    每组数据第一行一个正整数n,表示有n个王国,1 <= n <= 20。
    接下来n行,每行n个整数,第i行第j个整数表示d_ij,保证有d_ii = 0, d_ij = -d_ji, |d_ij| <= 10^6。

    Output

    每组数据输出一行,按照升序输出所有可能的王国编号,空格隔开,如果没有一个王国能满足条件,输出一个0。

    Sample Input

    1
    3
    0 -3 1
    3 0 -2
    -1 2 0

    Sample Output

    1 3

    HINT

    Source

  • 相关阅读:
    100到简单加减乘除算法的程序
    安卓日程管理系统中的bug
    绑定到Collection与绑定到CollectionViewSource的不同及解决方案
    【WPF】完美的布局不留白——解决WrapPanel右侧留白问题
    WPF里最简单的控件的Style你能写对么?(默认Style是有问题的)
    WPF Bug清单之(13)——应该出现却没有出现的ListView水平滚动条
    [WPF Bug清单]之(12)——与自定义Attached Property相关的Binding Path运行时错误
    请争取你可以拥有的——即使你不在乎
    C#编码风格——using语句的位置
    【WPF】实现QQ中的分组面板(2)——添加动画
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4633337.html
Copyright © 2011-2022 走看看