题目
思路
- 用一个对角线上颜色相同,间隔3个对角线上颜色相同,一共分为3组;
- 考虑在c种颜色中,选择3种,分配给这3组,共\(A(n, 3)\)种选法;
- dfs枚举排列方案,对每种方案计算花费,取最优即可。
总结
- dfs枚举排列方案;
代码
点击查看代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
using LL = long long;
const int N = 510, C = 35;
int d[C][C];
int cnt[3][C];
int cost[3][C];
bool vis[C];
int n, m;
int ans = 2e9;
void dfs(int dep, int sum)
{
if (dep == 3)
{
ans = min(ans, sum);
return;
}
for (int i = 1; i <= m; i ++)
if (vis[i] == false)
{
vis[i] = true;
dfs(dep + 1, sum + cost[dep][i]);
vis[i] = false;
}
}
void solv()
{
cin >> n >> m;
// 转换代价
for (int i = 1; i <= m; i ++)
for (int j = 1; j <= m; j ++)
cin >> d[i][j];
// 统计三组、每种颜色个数
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
{
int c; cin >> c;
cnt[(i + j) % 3][c] ++;
}
// 计算三组、转换为每种颜色的花费
for (int i = 0; i < 3; i ++)
{
for (int j = 1; j <= m; j ++)
{
int t = 0;
for (int k = 1; k <= m; k ++)
t += d[k][j] * cnt[i][k];
cost[i][j] = t;
}
}
// 枚举A(m, 3)
dfs(0, 0);
cout << ans << '\n';
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
solv();
return 0;
}