HDU2296(AC 로봇 + DP)
Ring
Problem Description
For the hope of a forever love, Steven is planning to send a ring to Jane with a romantic string engraved on. The string’s length should not exceed N. The careful Steven knows Jane so deeply that he knows her favorite words, such as “love”, “forever”. Also, he knows the value of each word. The higher value a word has the more joy Jane will get when see it. The weight of a word is defined as its appeared times in the romantic string multiply by its value, while the weight of the romantic string is defined as the sum of all words’ weight. You should output the string making its weight maximal.
Input
The input consists of several test cases. The first line of input consists of an integer T, indicating the number of test cases. Each test case starts with a line consisting of two integers: N, M, indicating the string’s length and the number of Jane’s favorite words. Each of the following M lines consists of a favorite word Si. The last line of each test case consists of M integers, while the i-th number indicates the value of Si. Technical Specification
Output
For each test case, output the string to engrave on a single line. If there’s more than one possible answer, first output the shortest one. If there are still multiple solutions, output the smallest in lexicographically order.
The answer may be an empty string.
Sample Input
2 7 2 love ever 5 5 5 1 ab 5
Sample Output
lovever abab
Hint
Sample 1: weight(love) = 5, weight(ever) = 5, so weight(lovever) = 5 + 5 = 10 Sample 2: weight(ab) = 2 * 5 = 10, so weight(abab) = 10
제목 대의:
n 길이를 초과하지 않는 문자열을 구성하여
∑i=1mhi 문자열에 나타나는 횟수
최대
만약 여러 개의 열이 모두 충족된다면 길이가 가장 작고, 길이가 같은 것이 있다면 사전 순서가 가장 작아야 한다
solution:
여러 모드열이 있고 길이가 크지 않아 AC 자동기를 구축할 생각을 하기 쉽다.그리고 방법이 분명해졌다. 트리뷰에서 DP를 뛰는 것이다.
f[i][j]는 길이가 i임을 나타내고 j호 노드의 최대 가치pre[i][j]는 f[i][j]의 가장 좋은 이동의 출처를 나타낸다.
이동은 매우 간단해서 할 말이 없지만 문자열을 요구할 때는 이동할 때 주의해야 한다. 세부 사항이 좀 많다
code:
#include
#include
#include
#include
#include
#include
using namespace std;
int sl,best,T,Max,n,len,son[70000][26],w[70000],num,hz[70000],que[70000],head,tail,f[55][70000],val[70000];
struct czy{
int a,b,c;
}pre[55][70000],id;
char ch[150],ans[1000],now[1000];
bool ok(int a,int b){
id=pre[a][b];
while(1){
now[id.a]=id.c+'a';
if(!id.a)
break;
id=pre[id.a][id.b];
}
for(int i=0;iif(ans[i]return false;
else
if(ans[i]>now[i])
return true;
return false;
}
bool check1(int a,int b,int c,char d){
id=pre[a-1][b];
while(1){
ch[id.a]=id.c+'a';
if(!id.a)
break;
id=pre[id.a][id.b];
}
ch[a-1]=d;
id=pre[a][c];
while(1){
now[id.a]=id.c+'a';
if(!id.a)
break;
id=pre[id.a][id.b];
}
for(int i=0;iif(now[i]return false;
else
if(now[i]>ch[i])
return true;
return false;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&Max,&n);
num=1;
memset(son,0,sizeof(son));
memset(hz,0,sizeof(hz));
memset(f,0,sizeof(f));
memset(w,0,sizeof(w));
for(int i=1;i<=n;i++){
scanf("%s",ch);
len=strlen(ch);
int x=1;
for(int j=0;jif(son[x][ch[j]-'a'])
x=son[x][ch[j]-'a'];
else
x=son[x][ch[j]-'a']=++num;
w[x]=i;
}
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
head=1;
tail=0;
for(int i=0;i<26;i++)
if(son[1][i]){
hz[son[1][i]]=1;
que[++tail]=son[1][i];
}
else
son[1][i]=1;
while(head<=tail){
int u=que[head++];
for(int i=0;i<26;i++)
if(son[u][i]){
hz[son[u][i]]=son[hz[u]][i];
que[++tail]=son[u][i];
}
else
son[u][i]=son[hz[u]][i];
}
for(int i=0;i<=Max;i++)
for(int j=1;j<=num;j++){
pre[i][j]=(czy){0,0,0};
f[i][j]=-1;
}
f[0][1]=0;
best=0;
sl=0;
for(int i=1;i<=Max;i++)
for(int j=1;j<=num;j++)
if(f[i-1][j]!=-1){
for(int k=0;k<26;k++){
int v=son[j][k];
if((f[i][v]==-1)||(f[i][v]1][j]+val[w[v]])||(f[i][v]==f[i-1][j]+val[w[v]])&&check1(i,j,v,k+'a')){
pre[i][v]=(czy){i-1,j,k};
f[i][v]=f[i-1][j]+val[w[v]];
}
}
}
memset(ans,0,sizeof(ans));
for(int i=1;i<=Max;i++)
for(int j=1;j<=num;j++){
if(f[i][j]>best||f[i][j]==best&&i==sl&&ok(i,j)){
best=f[i][j];
sl=i;
id=pre[i][j];
while(1){
now[id.a]=id.c+'a';
if(!id.a)
break;
id=pre[id.a][id.b];
}
for(int k=0;kfor(int i=0;iputchar(ans[i]);
puts("");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
HDU4758 Walk Through Squares AC 자동기 & &dp이 문제는 그때 할 때 수론제라고 생각했는데 01열 두 개가 포함돼 있었다. 경기 후에 문자열이라고 듣고 그럴 가능성이 높았다.어제 팀원들이 이 문제를 물었는데 AC자동기를 배운 후에 많이 간단해졌다고 느꼈다.그때는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.