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