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

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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章