hdu 4901 DP

来源:互联网 发布:南极旅游 知乎 编辑:程序博客网 时间:2024/06/05 02:05

dp1【i】【1】【j】表示前i个包含第i个数异或为j的种类数

dp1【i】【0】【j】表示前i个不包含第i个数异或为j的种类数

dp2【i】【j】表示后i个数相与为j的种类数

注意初始化

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const __int64 MOD = 1e9 + 7;__int64 dp1[1100][2][1100], dp2[1100][1100];int num[1100], N;int main(){    int T;    scanf( "%d", &T );    while( T-- ){        scanf( "%d", &N );        for( int i = 1; i <= N; i++ ){            scanf( "%d", &num[i] );        }        memset( dp1, 0, sizeof( dp1 ) );        dp1[1][1][num[1]]++;        dp1[1][0][0] = 1;        for( int i = 2; i <= N; i++ ){            for( int j = 0; j <= 1024; j++ ){                dp1[i][1][j^num[i]] = ( dp1[i][1][j^num[i]] + dp1[i-1][1][j] + dp1[i-1][0][j] ) % MOD;            }            for( int j = 0; j <= 1024; j++ ){                dp1[i][0][j] = ( dp1[i][0][j] + dp1[i-1][1][j] + dp1[i-1][0][j] ) % MOD;            }        }        memset( dp2, 0, sizeof( dp2 ) );        dp2[N][num[N]]++;        for( int i = N - 1; i >= 1; i-- ){            dp2[i][num[i]]++;            for( int j = 0; j <= 1024; j++ ){                dp2[i][j] = ( dp2[i][j] + dp2[i+1][j] ) % MOD;            }            for( int j = 0; j <= 1024; j++ ){                dp2[i][j&num[i]] = ( dp2[i][j&num[i]] + dp2[i+1][j] ) % MOD;            }        }        __int64 ans = 0;        for( int i = 1; i < N; i++ ){            for( int j = 0; j <= 1024; j++ ){                ans = ( ans + dp1[i][1][j] * dp2[i+1][j] ) % MOD;            }        }        printf( "%I64d\n", ans );    }    return 0;}


0 0
原创粉丝点击