戒指

来源:互联网 发布:淘宝发布保健品 编辑:程序博客网 时间:2024/06/08 16:25

题目

S计划送给J一枚戒指,以示他们的爱情天长地久
同时,S打算在戒指上刻写一些语句,以增加它的寓意。可惜戒指的大小有限,最多只能被刻入N个字母。细心的S非常了解J,知道她喜欢的单词,例如love, forever等等,同时他也知道这些单词都存在一个“愉悦值”,值越高的单词越能取悦J。
现在,S希望刻入一条字符串,使得各个单词在字符串中出现的次数 × 单词愉悦值之和尽可能的大。
1. 1 <= T <= 15
2. 1 <= N <= 50,1 <= M <= 100
3. 1 <= 单词长度 <= 10
4. 1 <= Hi <= 100
5. 数据保证不出现重复的单词
6. 对于每组数据输出一行,为在戒指上刻入的字符串。
如果有多解,则输出长度最短的解,若依然有多接则输出字典序最小的解。
答案有可能为空串。

分析

虽然这题的附加要求有很多:长度,字典序。
不过没关系,这题仍然可以用dp来处理。
具体的:
f[i,j]ij
same[i,j]ij
那么f[i+same[j,k],k]=max(f[i,j]+v[k],f[i+same[j,k],k])
而我们再记录两个值:
le[i,j]ans[i,j]ij
到此便可以很好的解决这个问题。
ps:我卡在这题很久的原因主要是same数组一直弄错。。还是要细心点,不要想当然,每一步都要经过严谨的思考来验证

var    t,i,j,k,ma,n,m,k1,k2:longint;    str:array[1..300] of string;    len,v:array[1..300] of longint;    c:array[1..500,1..300] of longint;    f,le:array[1..500,1..300] of longint;    ans:array[1..500,1..300] of string;we:string;function max(l,r:longint):longint;begin    if l<r then exit(r);exit(l);end;function get(x,y:string):longint;var i,j,lenx,leny,an,st:longint;p:boolean;begin    lenx:=length(x);leny:=length(y);an:=0;    if x=y then st:=2 else st:=1;    for i:=st to lenx do begin        if lenx-i+1>leny then continue;P:=true;        for j:=i to lenx do            if x[j]<>y[j-i+1] then begin p:=false;break;end;        if not p then continue;        an:=max(an,lenx-i+1);    end;exit(an);end;begin    readln(t);    for t:=1 to t do begin        readln(n,m);        for i:=1 to m do begin readln(str[i]);len[i]:=length(str[i]);end;        for i:=1 to m do            for j:=1 to m do begin            c[i,j]:=get(str[i],str[j]);            end;        fillchar(f,sizeof(f),0);        for i:=1 to 500 do        for j:=1 to 300 do ans[i,j]:='';        k:=k;        for i:=1 to m do begin            read(v[i]);            f[len[i],i]:=v[i];            ans[len[i],i]:=str[i];le[len[i],i]:=len[i];        end; readln;        for i:=1 to n do            for j:=1 to m do if f[i,j]>0 then                for k:=1 to m do begin                    k2:=i+len[k]-c[j,k];                    if f[k2,k]<f[i,j]+v[k] then begin                       f[k2,k]:=f[i,j]+v[k];                       k1:=len[k]-c[j,k];                       ans[k2,k]:=ans[i,j]+copy(str[k],c[j,k]+1,k1);                       le[k2,k]:=le[i,j]+k1;                    end else                    if (f[k2,k]=f[i,j]+v[k])and(le[k2,k]=le[i,j]+len[k]-c[j,k])and(ans[k2,k]>ans[i,j]+copy(str[k],c[j,k]+1,len[k]-c[j,k])) then begin                         ans[k2,k]:=ans[i,j]+copy(str[k],c[j,k]+1,len[k]-c[j,k]);                         le[k2,k]:=le[i,j]+len[k]-c[j,k];                    end                    else if (f[k2,k]=f[i,j]+v[k])and(le[k2,k]>le[i,j]+len[k]-c[j,k]) then begin                         ans[k2,k]:=ans[i,j]+copy(str[k],c[j,k]+1,len[k]-c[j,k]);                         le[k2,k]:=le[i,j]+len[k]-c[j,k];                    end;                end;        ma:=0;we:='';        for i:=1 to n do            for j:=1 to m do            if ma<f[i,j] then begin ma:=f[i,j];we:=ans[i,j];end            else if (ma=f[i,j])and(we>ans[i,j]) then we:=ans[i,j];        writeln(we);    end;close(input);close(output);end.
0 0
原创粉丝点击