k개의 알파벳을 학습하여 N개의 남극언어 중 몇 개를 읽을 수 있는가인데, 시간 복잡도 계산 안하고 그냥 재귀로 돌려봤다
매번 모든 알파벳을 검사하기는 힘들다. 그리고 어차피 알파벳은 한번만 배우면 계속 쓰일 수 있다. 그럼 각 단어마다 알파벳의 존재여부를 체크하여 저장할 수가 있는데, 한 단어에서 x번째 알파벳이 사용되었다/안되었다(0/1) 로 구분하면 26자리 2진수 (최대 226−1) 로 표현할 수 있다. 그럼 ACE 는 0 00000 00000 00000 00000 10101 로 표현된다.
소스는 1번째...26번째로 해서 비트가 왼쪽으로 하나씩 밀려있다.
A~Z 중에 k개를 선택했을 때 읽을 수 있는 최대 단어의 갯수를 반환하면서, 그 최대값을 갱신하도록 했다.
그리고 "K개의 글자"에 남극언어에 들어가는 ANTA,TICA 도 포함되어야 한다. (이것때문에 한참 틀렸다) 즉, 5개의 글자(ANTIC)를 반드시 배워야한다는 것이다.
#include <bits/stdc++.h>
using namespace std;
#define ANTATICA 1065483
typedef long long lld;
int n, k;
lld words[51];
int f(int pos, int alphabet, lld bit){
if(pos > k || alphabet > 27) return 0;
if(pos == k){
int i, cnt=0;
for(i=0; i<n; ++i){
cnt += (words[i]&bit) == words[i];
}
return cnt;
}
int i, r=0;
for(i=alphabet; i<=26; ++i){
if((bit&(1<<i))==0){
r = max(r, f(pos+1, i+1, bit|(1<<i)));
}
}
return r;
}
int main(){
scanf("%d %d ", &n, &k);
for(int i=0; i<n; ++i){
char s[16]={};
scanf("%s ", s);
int j, len=strlen(s)-4;
lld hashValue = 1LL;
for(j=4; j<len; ++j)
hashValue |= (1<<(s[j]-'a'+1));
words[i] = hashValue | ANTATICA;
}
k -= 5;
if(k < 0) puts("0");
else printf("%d", f(0, 1, ANTATICA));
// antic 의 비트값
// lld bit = 1LL;
// bit |= (1<<('a'-'a'+1));
// bit |= (1<<('n'-'a'+1));
// bit |= (1<<('t'-'a'+1));
// bit |= (1<<('i'-'a'+1));
// bit |= (1<<('c'-'a'+1));
// printf("%lld", bit);
return 0;
}
댓글 없음:
댓글 쓰기