SGU_225
由于在dp的时候需要记录上面两行放置马的状态,以及马的数量,这样状态数就相当多了,直接交写完的dp就TLE了。
暂时没有想到好的办法,所以拿自己dp的程序打了个表交上去AC了。
// 注意:这个程序是用来打表的,并不是可以直接提交的程序。 #include<stdio.h> #include<string.h> #define MAXD 20 #define HASH 100007 #define SIZE 2000010 int N, K, ucode[MAXD], dcode[MAXD], ncode[MAXD], num; struct Hashmap { int head[HASH], next[SIZE], state[SIZE], size; long long f[SIZE]; void init() { memset(head, -1, sizeof(head)); size = 0; } inline void push(int st, long long ans) { int i, h = st % HASH; for(i = head[h]; i != -1; i = next[i]) { if(st == state[i]) { f[i] += ans; return ; } } state[size] = st, f[size] = ans; next[size] = head[h]; head[h] = size ++; } }hm[2]; inline void decode(int *ucode, int *dcode, int m, int st) { int i; num = st & ((1 << 7) - 1); st >>= 7; for(i = m; i >= 0; i --) { dcode[i] = st & 1; st >>= 1; } for(i = m; i >= 0; i --) { ucode[i] = st & 1; st >>= 1; } } inline int encode(int *ucode, int *dcode, int m) { int i, st = 0; for(i = 0; i <= m; i ++) { st <<= 1; st |= ucode[i]; } for(i = 0; i <= m; i ++) { st <<= 1; st |= dcode[i]; } st <<= 7; st |= num; return st; } void dfs(int cur, int k, int j) { if(j > N) { hm[cur ^ 1].push(encode(dcode, ncode, N + 1), hm[cur].f[k]); return ; } if(num < K && dcode[j - 1] == 0 && ucode[j] == 0 && ucode[j + 2] == 0 && dcode[j + 3] == 0) { ++ num; ncode[j + 1] = 1; dfs(cur, k, j + 1); -- num; } ncode[j + 1] = 0; dfs(cur, k, j + 1); } void dpblank(int cur) { int k; for(k = 0; k < hm[cur].size; k ++) { decode(ucode, dcode, N + 1, hm[cur].state[k]); dfs(cur, k, 1); } } void solve() { int i, j, cur = 0; long long ans = 0; hm[cur].init(); hm[cur].push(0, 1); memset(ucode, 0, sizeof(ucode)); memset(dcode, 0, sizeof(dcode)); memset(ncode, 0, sizeof(ncode)); for(i = 1; i <= N; i ++) { hm[cur ^ 1].init(); dpblank(cur); cur ^= 1; } for(i = 0; i < hm[cur].size; i ++) if((hm[cur].state[i] & ((1 << 7) - 1)) == K) ans += hm[cur].f[i]; printf("%I64d", ans); } int main() { freopen("SGU_225(1).cpp", "w", stdout); printf("#include<stdio.h>\n"); printf("#include<string.h>\n"); printf("#define MAXD 110\n"); printf("int N, K;\n"); printf("long long ans[MAXD][MAXD];\n"); printf("int main()\n"); printf("{\n"); for(N = 1; N <= 10; N ++) for(K = 1; K <= N * N; K ++) { printf("\tans[%d][%d] = ", N, K); if(N > 3 && K > (N * N + 1) / 2) printf("0"); else solve(); printf("ll;\n"); } printf("\twhile(scanf(\"%%d%%d\", &N, &K) == 2)\n"); printf("\t{\n"); printf("\t\tprintf(\"%%I64d\\n\", K == 0 ? 1 : ans[N][K]);\n"); printf("\t}\n"); printf("\treturn 0;\n"); printf("}\n"); return 0; }