题目描述
连连看是一款非常有意思的游戏。
我们可以把任意两个在图的在边界上的相同的方格一起消掉,比如把两个 4 4 4消掉以后
每次消掉两个方格的时候,都有会获得一个分数,第 i i i 次消的分数为 i × i× i×方格的值。比如上面的消法,是第一次消,获得的分数为 1 × 4 = 4 1×4=4 1×4=4
请你帮忙最优操作情况下,获得的分数最多为多少。
分析
结果填空题, 不用考虑时间复杂度,直接暴力搜索
注意, 每次只能消掉边界上值相同的两个格子
答案
分数最大为 89 89 89
实现
// 跑了十多分钟还没有跑完, 复杂度实在太高了, 应该还可以剪枝
// 答案一直停留在89
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int map[4][4] = {{1,4,2,5},{2,1,2,1},{3,1,3,2},{2,5,3,4}};
bool vis[4][4]; // 是否已经被消除
int dx[] = {0,1,0,-1}, dy[] = {1,0,-1,0};
int ans = -1;
bool check(int x, int y) // 检查当前格子是否为边界
{
if(vis[x][y]) return false; // 格子已经被消除过
for(int i=0; i<4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || nx >= 4 || ny < 0 || ny >= 4) return true; // 上下左右的格子存在出界的情况, 则当前的格子一定是边界
if(vis[nx][ny]) return true; // 上下左右的格子存在被消除的情况, 则当前的格子一定是边界
}
return false;
}
void dfs(int step, int score)
{
cout << ans << endl;
ans = max(ans, score); // 更新最高得分
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
if(!check(i,j)) continue; // 遍历整个地图, 先找到一个为边界的格子
for(int k=0; k<4; k++)
{
for(int p=0; p<4; p++)
{
if((i==k && j==p) || !check(k,p) || map[i][j] != map[k][p]) continue; // 再遍历整个地图, 找到一个和[i,j]值相等且为边界的格子
vis[i][j] = vis[k][p] = 1;
dfs(step+1,score + step*map[i][j]);
vis[i][j] = vis[k][p] = 0; // 回溯
}
}
}
}
return;
}
int main()
{
dfs(1,0);
cout << ans << endl;
return 0;
}