srm 554 dv2 1000pt
好暴力的dp啊。。有木有更简单的方法呢?
# include <cstdio> # include <algorithm> # include <string> # include <cstring> # include <iostream> # define MOD 1234567891 using namespace std; typedef long long ll; ll dp[50][10][4][4][4][4]; class TheBrickTowerHardDivTwo { public: int find(int C, int K, int H) { ll n,k,a,b,c,d,x,y,z,i,ans=0ll; for (a=0;a<C;++a) for (b=0;b<C;++b) for (c=0;c<C;++c) for (d=0;d<C;++d) { ll p = (a==b)+(b==c)+(c==d)+(a==d); dp[1][p][a][b][c][d] = 1; } for (n=2;n<=H;++n) for (k=0;k<=K;++k) for (a=0;a<C;++a) for (b=0;b<C;++b) for (c=0;c<C;++c) for (d=0;d<C;++d) for (x=0;x<C;++x) for (y=0;y<C;++y) for (z=0;z<C;++z) for (i=0;i<C;++i) { ll p = (a==b)+(b==c)+(c==d)+(a==d); p += ((a==x)+(b==y)+(c==z)+(d==i)); if (p<=k) { dp[n][k][a][b][c][d] += dp[n-1][k-p][x][y][z][i]; dp[n][k][a][b][c][d] %= MOD; } } for (k=0;k<=K;++k) for (n=1;n<=H;++n) for (a=0;a<C;++a) for (b=0;b<C;++b) for (c=0;c<C;++c) for (d=0;d<C;++d) { ans += dp[n][k][a][b][c][d]; ans %= MOD; } return ans; } };