// RESTORE 20190225// #알고리즘 #프로그래밍 #종만북 #난이도:중#include <iostream>#include <cstring>#include <string>#include <vector>#include <algorithm>#include <cmath>#include <cstdio>usingnamespacestd;template<typenameT>voidvectorclear(vector<T>&vec_obj){vector<T>temp_obj;temp_obj.swap(vec_obj);}voidstringclear(string&str){stringthrowawaystr;str.swap(throwawaystr);}//기본셋intk;vector<string>sts;intoverlap[15][15];intcashe[15][1<<15];intover(inta,intb){intasize=sts[a].size();intbsize=sts[b].size();for(inti=0;i<asize;i++){for(intj=0;j<asize-i;j++){if(sts[a][i+j]==sts[b][j]){if((j==asize-i-1)||((bsize-1)==j)){returnoverlap[a][b]=j+1;}continue;}break;}}return0;}//오버랩 함수 , 겹치는 경우를 포함했다.intrestore(intlast,intused){if(used==((1<<k)-1)){return0;}//기저int&ret=cashe[last][used];if(ret!=-1){returnret;}//메모이제이션ret=0;for(intnext=0;next<k;next++){if((used&1<<next)==0){intret2=overlap[last][next]+restore(next,used+(1<<next));ret=max(ret,ret2);}}returnret;}//최대 오버랩 길이stringrecon(intlast,intused){if(used==((1<<k)-1)){return"";}//기저for(intnext=0;next<k;next++){if(used&(1<<next)){continue;}intifused=restore(next,used+(1<<next))+overlap[last][next];if(restore(last,used)==ifused){return(sts[next].substr(overlap[last][next])+recon(next,used+(1<<next)));}}//overlap 이전을 잘라 버리는 substr. 이것과 맨 처음 글자를 더하면 된다.return"!!ops!!";}intmain(){intC;cin>>C;while(C--){fill(cashe[0],cashe[0]+(15*(1<<15)),-1);fill(overlap[0],overlap[0]+15*15,0);vectorclear(sts);//초기화는 언제나 필수적이다.cin>>k;intputk=k;while(putk--){stringa;cin>>a;sts.push_back(a);}//입력끝for(intp=0;p<k;p++){for(inti=0;i<k;i++)for(intj=0;j<k;j++)if(i!=j){over(i,j);if((over(i,j)==sts[i].size())){sts[i]=sts[j];}if((over(i,j)==sts[j].size())){sts[j]=sts[i];}}//오버랩 작성, 겹치는 것 정제 (겹치면 그냥 동일하게 바꾸는 형식) 이걸 반복!for(inti=0;i<k;i++)for(intj=0;j<k;j++)if(i!=j){over(i,j);}}//다시 오버랩 정리.intret3=0;for(intm=0;m<k;m++){ret3=max(ret3,restore(m,1<<m));}//최대 오버랩 길이 구하기for(intm=0;m<k;m++){if(ret3==restore(m,1<<m)){cout<<sts[m]+recon(m,1<<m)<<endl;break;}//최대 오버랩 길이와 restore이 같은 경우가 맨 첫 글자의 m}}return0;}
5년 전
0개의 댓글이 있습니다.
정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면
온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야
합니다. 현재 문제를 푸셨습니다.
시나브로
오버랩 계산을 여러번 하는 형식으로 풀었는데,
책의 예시는 물론 다른 질문에 있는
1 4 a b c aabcaaaaa 와 같은 것도 잘 되는데 왜 오답이 날까요.. 도저히 모르겠어서 질문해봅니다.
RESTORE
5년 전