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] << " "; } return 0; }