您的位置:首页 > 其它

SGU 225 Little Knights

2012-04-21 20:29 274 查看
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
[K]);\n");
printf("\t}\n");
printf("\treturn 0;\n");
printf("}\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: