#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<pair<int, int>> houses;
vector<pair<int, int>> total_chickens;
int N, M;
int calc(vector<pair<int, int>> chickens)
{
int sum = 0;
// 각각의 집에 대해 최단 치킨 거리를 구한다.
for(auto o : houses)
{
int min_ = 1000000;
for(auto p : chickens)
{
min_ = min(min_, abs(o.first-p.first) + abs(o.second - p.second));
if(min_==1)break;
}
sum += min_;
// 구한 결과를 반환한다.
}
return sum;
}
// 조합적으로 겹치는 경우
// 벡터에 {1, 2, 3, 4, 5} 있는 경우랑
// {2, 1, 3, 4, 5} 있는 경우.. 모두 다른 케이스로 들어간다..
int dfs(vector<pair<int, int>> chickens, int level, bool visited[],int id)
{
if(level == M) // M 개를 골랐다!
{
int a = calc(chickens);
// cout << a << " ";
return a;
}
// int sz = chickens.size();
int min_ = 100000;
for(int i=id; i<total_chickens.size(); i++)
{
if(!visited[i])
{
// pair<int, int> tmp = chickens.at(i);
chickens.push_back(total_chickens.at(i));
visited[i] = true;
min_ = min(min_, dfs(chickens, level+1, visited, id+1));
chickens.pop_back();
visited[i] = false;
}
}
return min_;
}
int main()
{
// N x N의 도시. (맵 형태.)
// 각 칸은 빈 칸, 치킨집, 집 (3개) 중 하나다. 도시는 (r,c)=(행,열)
// 1부터 시작함.
// 치킨 거리 = 집과 가장 가까운 치킨집 가시의 거리임.
// 모든 집의 치킨 거리의 합..
// 맨하탄 거리로 계산한다.
// 0=빈칸, 1=집, 2=치킨집
// 치킨집 중 M개 빼고 없앤 후, 치킨 거리 최소되도록 하기.
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M;
int tmp;
int cnt=0;
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cin >> tmp;
if (tmp == 1)
{
houses.push_back(make_pair(i, j));
}
else if(tmp == 2)
{
total_chickens.push_back(make_pair(i, j));
}
}
}
bool *visited = new bool[total_chickens.size()];
for(int i=0; i<total_chickens.size(); i++)
{
visited[i] = 0;
}
int level = 0;
vector<pair<int, int>> chickens;
cout << dfs(chickens, level, visited, 0);
}
예제는 다 맞는데 시간초과 ㅇㅅㅇ;;
조합인데 순열처럼 쓰려고 id 변수까지 해줬는데 왜 시간초과?
레퍼런스로 해서 넘겨줘봐 그리고 지금 보니까 조합이 아니라 순열 아님? visited만 체크해서 조합을 만들수 있나? 변수 하나 만들어서 체크해야할텐데
n개중에 r개 고르는거라 순열로 해야 중복체크 안해서 효율적이지.. 직전에 i번 치킨집을 골랐으면 그 다음은 i+1번째 치킨집부터 고르게 만들어서 순열 구현한거
지금 다시 생각해보니까 치킨집을 0개부터 시작해서 추가하는게 아니라.. 풀로 차있게 한 다음에 하나씩 빼는거 같기도 하고 그런듯? 집마다 최단거리 dp 써서 치킨집 없앨때마다 dp값보다 거리 멀어질때만 갱신하고??
아니 변수 넣어서 체크해보니까 예제 2번 치킨집 5개 중에 2개 뽑는건데 16번 calc 호출하잖아 조합 문제임
정확히 너 조합이 M개면 (M-1)^2개 호출됨 치킨집6개중에 2개 뽑으랬더니 25번 호출되네
조합 구현을 잘못했다는 말이지??
ㅇㅇ 조합도 아니고 순열도 아님
ㅋㅋㅋㅋㅋㅋ id를 i로 바꿔야했네
아니 ㅁㅊ id를 i로 바꿔주기만 했는데 바로 성공이네 4ms ㅅㅂ 개어이x
어쩐지 좀 이상하드라 ㅋㅋㅋㅋㅋㅋㅋㅋ큐ㅠㅠㅠㅠ 슈밤
아 그 id가 조합체크 부분이였나보네 ㅋㅋ ㅊㅋ
감사합니당 ㅠㅠㅜ