hdu 1693 插头DP

来源:互联网 发布:项目管控软件 编辑:程序博客网 时间:2024/06/09 23:03

第一道插头DP。。。。。

巨弱啊。。。。。

看了论文,不确定从上一行到下一行怎么转移,所以不敢敲啊。。。。

最后看了下别人的模版。。。。。我原来想的还是对的啊。。。。。

其实插头DP我感觉跟那个炮兵阵地差不多。。。。但是这个是按格转移的。。。。

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;__int64 dp[12][12][1<<12];int maps[12][12];int N, M;int main(){    int T, Case = 1;    scanf( "%d", &T );    while( T-- ){        scanf( "%d%d", &N, &M );        for( int i = 1; i <= N; i++ ){            for( int j = 1; j <= M; j++ ){                scanf( "%d", &maps[i][j] );            }        }        memset( dp, 0, sizeof( dp ) );        dp[0][M][0] = 1;        for( int i = 1; i <= N; i++ ){            //这个的意思是从上一行的M转移到这一行的1            for( int k = 0; k < ( 1 << M ); k++ ){//注意这里最大是M。。。。。。。。。。                dp[i][0][k<<1] = dp[i-1][M][k];            }            for( int j = 1; j <= M; j++ ){                for( int k = 0; k < ( 1 << ( M + 1 ) ); k++ ){                    int tt1 = ( 1 << ( j - 1 ) );                    int tt2 = ( 1 << j );                    bool t1 = k & tt1;//注意这里不能是int。。。。。。WA了半天。。。。                    bool t2 = k & tt2;                    if( maps[i][j] ){                        dp[i][j][k] = dp[i][j-1][k^tt1^tt2];                        if( t1 != t2 ){                            dp[i][j][k] += dp[i][j-1][k];                        }                    }else{                        if( t1 == 0 && t2 == 0 ){                            dp[i][j][k] = dp[i][j-1][k];                        }else{                            dp[i][j][k] = 0;                        }                    }                }            }        }        printf( "Case %d: There are %I64d ways to eat the trees.\n",  Case++, dp[N][M][0] );    }    return 0;}


0 0
原创粉丝点击