HDU计算机学院大学生程序设计竞赛(2015’12)1007 Pick Game

来源:互联网 发布:centos c 4.9.4 编辑:程序博客网 时间:2024/05/05 21:29
题意:

有n*m的格子 v[i][j]代表该位置的价值 (n,m<=5)

两个人轮流选格子 只有相邻格子至少有两个为空的才能选

选择之后该格子变空,得到v[i][j]

求问先手能达到的最大价值

 

爆搜可过,状态不多。

记忆化搜索用map记录

4000ms过  无剪枝

还可以加一些剪枝

#include<iostream>#include<cstring>#include<cstdio>#include<map>#include<cmath>#include<algorithm>using namespace std;int fa[15][15],v[15][15],c[15][15];int n,m;map<int, int> f;int dfs(int x, int sum){    int i,j,k;    int ans = sum;    if (x == n*m) return 0;    int pre = 0;    for (i = 1; i <= n; i++)        for (j = 1; j <= m; j++) pre += fa[i][j] << ((i - 1)*m + j - 1);    if (f[pre]) return f[pre];    for (i = 1; i <= n; i++)        for (j = 1; j <= m; j++)            if (c[i][j]<= 2&&fa[i][j]==0)            {                fa[i][j] = 1;                c[i-1][j]--;                c[i][j-1]--;                c[i+1][j]--;                c[i][j+1]--;                ans=min(ans, dfs(x+1, sum-v[i][j]));                fa[i][j]=0;                c[i-1][j]++;                c[i][j-1]++;                c[i+1][j]++;                c[i][j+1]++;            }    return f[pre]=sum-ans;}int main(){    int i,j,k;    int T;    scanf("%d", &T);    while (T--)    {        f.clear();        memset(fa, 0, sizeof(fa));        scanf("%d%d", &n, &m);        int sum = 0;        for (i = 1; i <= n; i++)            for (j = 1; j <= m; j++)            {                scanf("%d", &v[i][j]);                sum += v[i][j];                c[i][j] = 4;                if (i==1||i== n) c[i][j]--;                if (j==1||j== m) c[i][j]--;            }        printf("%d\n", dfs(0, sum));    }    return 0;}

 

  

0 0
原创粉丝点击