제목대로 가르침받았다.. 후 너무 어렵당 다시 풀어봐야겠다.
정리할게 너무 많다.
우선 비트마스크는 보통 모든 부분수열을 찾을 때 사용한다. 따라서 선택가능한 K개의 알파벳중 일일이 알파벳을 선택했는지의 여부는 재귀를 통해 해결한다.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int count(int mask, vector<int> &words) {
//알파벳 z까지 확인했으니 이제 읽을 수 있는 단어가 있는지 확인해보자
int cnt = 0;
for (int i = 0; i < words.size();i++) {
if ((words[i] & (1 << 26) - 1 - mask) == 0) cnt++;
}
return cnt;
}
int DFS(int index, int k, int mask, vector<int> words) {
if (k < 0) return 0;//why 0?
if (index == 26) return count(mask, words);//마지막 알파벳까지 왔으면 count세고 와라
int ans = 0;
//이번 알파벳은 선택하고, 재귀 다녀오렴
int t1 = DFS(index + 1, k - 1, mask | (1 << index), words);
if (ans < t1) ans = t1;
//이제 안고르고 재귀 다녀와보렴
//그런데, a n t i c 는 꼭 골라야하는거 알지? 얘네 안고르면 그냥 통과시킬겡ㅎ
if (index != 'a' - 'a' && index != 'n' - 'a' && index != 't' - 'a' && index != 'i' - 'a' && index != 'c' - 'a') {
t1 = DFS(index + 1, k, mask, words);
if (ans < t1) ans = t1;
}
return ans;
}
int n, m;
int main() {
ios_base::sync_with_stdio(false);
//freopen("in1.txt", "rt", stdin);
cin >> n >> m;
vector<int> words(n);
for (int i = 0; i < n; i++) {
string s;
cin >> s;
for (char j : s) {
// |=을 통해 중복을 제외하고 넣기 가능
words[i] |= (1 << (j - 'a')); //글자의 중복을 제거하고 비트마스킹
}
}
cout << DFS(0, m, 0, words) << '\n';
return 0;
}