Tony's Log

Algorithms, Distributed System, Machine Learning

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

A combination of different DP passes. https://www.hackerrank.com/challenges/lego-blocks/editorial

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

typedef unsigned long long ULL;

const ULL mod = 1000000007;

ULL pow(ULL a, int p)
{
    ULL ans = 1;
    while (p)
    {
        if (p % 2) ans = ans * a % mod;
        a = a * a % mod;
        p /= 2;
    }
    return ans;
}

int main(void)
{
    //    Pre-calculation: one row count DP
    vector<ULL> f(1111, 0);
    f[0] = 1;
    for (int i = 1; i <= 1000; i++)
        for (int j = 1; j <= 4; j++)
            if (i - j >= 0) f[i] = (f[i] + f[i - j]) % mod;

    int t; cin >> t;
    while (t--)
    {
        int n, m; cin >> n >> m;

        //    All-row count
        vector<ULL> g(m + 1, 0);
        for (int i = 1; i <= m; i++) g[i] = pow(f[i], n);

        vector<ULL> h(m + 1, 0);
        h[1] = 1; // only possible with 1x1x1
        for (int i = 2; i <= m; i++)
        {
            h[i] = g[i];
            //    remove all un-solid cases
            ULL tmp = 0;
            for (int j = 1; j<i; j++)
                tmp = (tmp + h[j] * g[i - j]) % mod;
            h[i] = (h[i] - tmp + mod) % mod;
        }
        cout << h[m] << "\n";
    }

    return 0;
}
posted on 2015-08-02 05:31  Tonix  阅读(840)  评论(0编辑  收藏  举报