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

21 篇文章 0 订阅
13 篇文章 1 订阅

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


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值