2012 Multi-University Training Contest 4[hdu4331~4339]

来源:互联网 发布:东京经济大学 知乎 编辑:程序博客网 时间:2024/05/18 08:33

hdu 4332 Constructing Chimney

状态压缩dp+矩阵优化, 256×256的暴力方法,幂矩阵的预处理和某项为0时的跳出优化,时间1s多, 还要消化下那个循环移位取最小的神优化能化到35×35

typedef long long ll;typedef unsigned int UI;using namespace std;const int SZ=256;const int mod=1000000007;struct Matrix{    ll m[SZ][SZ];}A[33];ll ans[2][SZ];void Mdebug(Matrix a){    for (int i=0; i<SZ; ++i)    {        for (int j=0; j<SZ; ++j)                printf("%d", a.m[i][j]);        puts("");    }}bool check(int x){    int b[10]={0};    for (int i=0; i<8; ++i)    {        if((x>>i)&1)b[++b[0]]=i;    }    if(b[0]&1)return false;    //printf("%d  %d\n", b[0], x);    for (int i=2; i<=b[0]; ++i)    {        if((b[i]-b[i-1]-1)&1)return false;    }    if((b[1]+8-b[b[0]]-1)&1)return false;    return true;}void init(){    clean(A, 0);    for (int i=0; i<SZ; ++i)    {        for (int j=0; j<SZ; ++j)        {            if((i&j)==0 && check(i|j))            {                A[1].m[i][j]=1;            }        }    }    A[1].m[0][0]=2;    //Mdebug(A);    for (int i=2; i<33; ++i)    {        for (int j=0; j<SZ; ++j)            for (int q=0; q<SZ; ++q)if(A[i-1].m[j][q])                for (int k=0; k<SZ; ++k)if(A[i-1].m[q][k])                    A[i].m[j][k]=(A[i].m[j][k]+A[i-1].m[j][q]*A[i-1].m[q][k]+mod)%mod;    }    for (int i=0; i<SZ; ++i)    {        A[0].m[i][i]=1;    }}int main (){    init();/// ³õʼ»¯±ä»»¾ØÕóºó//    for (int i=0; i<20; ++i)//        printf("%d\n", A[i].m[0][0]);//    freopen("1002.in", "r", stdin);//    freopen("1002a.out", "w", stdout);    int cas; scanf("%d", &cas);    for (int I=1; I<=cas; ++I)    {        int n; scanf("%d", &n);        clean(ans[0], 0);        ans[0][0]=1;        int t=0;        for (int i=1; n; n>>=1, ++i)        {            if(n&1)            {                t^=1; clean(ans[t], 0);                for (int q=0; q<SZ; ++q)if(ans[t^1][q])                    for (int j=0; j<SZ; ++j)if(A[i].m[j][q])                        ans[t][j]=(ans[t][j]+ans[t^1][q]*A[i].m[j][q]+mod)%mod;            }        }        //for (int i=0; i<46; ++i) ans=(ans+B.m[i][0])%mod;        //printf("11 %I64d\n", ans);        //Mdebug(B);        printf("Case %d: %I64d\n", I, ans[t][0]);    }    return 0;}


 

原创粉丝点击