123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- Program Pro_6; {例6的动态规划解法}
- Const Fin ='Input.txt'; {输入文件名}
- Fou ='Output.txt'; {输出文件名}
- Type Kus =Array[0..1160] Of Byte; {记录数组的类型说明}
- Zis =Array[0..1160] Of Integer;
- Var Ku :Array[1..1000] Of ^kus; {记录决策的数组}
- Shu,Shu1 :Array[1..1000] Of Byte;
- Zi :Array[0..1] Of Zis; {记录状态的数组}
- Use1 :Array[0..20,0..20,0..20] Of Integer; {记录三个数的组合的数组}
- Use2 :Array[0..1160,1..3] Of Byte; {将一个数转化为三个数组合的数组}
- Total,I,M,N,P,N1 :Integer;
- F :Text;
- W1,W2,W3,W4 :Word;
- {--Init--}
- Procedure Init; {初始化}
- Var I,J:Integer;
- Begin
- Assign(F,Fin);
- Reset(F);
- Readln(F,N1,M,P);
- For I:=1 To N1 Do
- Read(F,Shu1[I]);
- Shu[1]:=Shu1[1];
- N:=1;
- For I:=2 To N1 Do
- If Shu1[I]<>Shu1[I-1] Then
- Begin Inc(N);Shu[N]:=Shu1[I];End;
- Close(F);
- End;
- {---Diduse----}
- Procedure Diduse; {将三个数组合的情况转化为一个序数与其对应}
- Var Qs :Array[1..3] Of Byte;
- Stop :Byte;
- I,J,K :Byte;
- {==Serch==}
- Procedure Serch(Depth,From:Byte); {搜索所有的组合情况}
- Var I:Byte;
- Begin
- If Depth=Stop+1 Then
- Begin
- Inc(Total);
- Use2[Total,1]:=Qs[1];Use2[Total,2]:=Qs[2];
- Use2[Total,3]:=Qs[3];
- Use1[Qs[1],Qs[2],Qs[3]]:=Total;Use1[Qs[1],Qs[3],Qs[2]]:=Total;
- Use1[Qs[2],Qs[1],Qs[3]]:=Total;Use1[Qs[2],Qs[3],Qs[1]]:=Total;
- Use1[Qs[3],Qs[1],Qs[2]]:=Total;Use1[Qs[3],Qs[2],Qs[1]]:=Total;
- End
- Else
- For I:=From To M-1 Do
- Begin
- Qs[Depth]:=I;
- Serch(Depth+1,I+1);
- End;
- End;
- Begin
- Total:=0;
- Fillchar(Qs,Sizeof(Qs),0);
- For I:=0 To M Do
- For J:=0 To M Do
- For K:=0 To M Do
- Use1[I,J,K]:=-1;
- Use2[0,1]:=0;Use2[0,2]:=0;Use2[0,3]:=0;
- Use1[0,0,0]:=0;
- For Stop:=1 To P-1 Do
- Serch(1,1);
- End;
- {-----Main-------} {主过程}
- Procedure Main;
- Var I,J,K,W1,W2,W3 :Integer;
- Q :Array[1..4] Of Byte;
- Begin
- For I:=1 To N Do
- Begin New(Ku[I]);End;
- Fillchar(Zi,Sizeof(Zi),0); {动态规划初始化}
- Fillchar(Ku[1]^,Sizeof(Ku[1]^),0);
- Zi[0][0]:=1;
- Fillchar(Q,Sizeof(Q),0);
- For I:=2 To N Do {动态规划求值}
- Begin
- For J:=0 To Total Do
- If Zi[0][J]<>0 Then
- Begin
- W1:=0;
- For K:=1 To 3 Do
- Begin Q[K]:=Use2[J,K];
- If Q[K]>=Shu[I-1] Then Inc(Q[K]);
- If Q[K]=Shu[I] Then W1:=K;
- End;{End For K}
- Q[4]:=Shu[I-1];
- If W1<>0 Then
- Begin
- W2:=Q[4];Q[4]:=Q[W1];Q[W1]:=W2;
- For K:=1 To 3 Do
- If Q[K]>Shu[I] Then Dec(Q[K]);
- W3:=Use1[Q[1],Q[2],Q[3]];
- If (Zi[1][W3]=0) Or (Zi[1][W3]>Zi[0][J]) Then
- Begin
- Zi[1][W3]:=Zi[0][J];
- Ku[I]^[W3]:=Shu[I];
- End;
- End {End If}
- Else
- Begin
- For K:=1 To 4 Do
- If Q[K]>Shu[I] Then Dec(Q[K]);
- For K:=1 To 4 Do {分四种情况决策}
- Begin
- Case K Of
- 1:W1:=Use1[Q[2],Q[3],Q[4]];
- 2:W1:=Use1[Q[1],Q[3],Q[4]];
- 3:W1:=Use1[Q[1],Q[2],Q[4]];
- 4:W1:=Use1[Q[1],Q[2],Q[3]];
- End;
- If W1<>-1 Then
- If (Zi[1][W1]=0) Or (Zi[1][W1]>Zi[0][J]+1) Then
- Begin
- Zi[1][W1]:=Zi[0][J]+1;
- W2:=Q[K];
- If W2>=Shu[I] Then Inc(W2);
- Ku[I]^[W1]:=W2;
- End;{End If}
- End;{End For K}
- End;{End For Else};
- End;{End For J}
- Zi[0]:=Zi[1];
- Fillchar(Zi[1],Sizeof(Zi[1]),0);
- End;{End For I}
- End;
- {-----Print---}
- Procedure Print; {打印结果}
- Var Pr,Pr1 :Array[1..1000] Of Integer;
- Now,Q :Array[1..4] Of Byte;
- I,J,K,Ps,W1,W2 :Integer;
- Begin
- Ps:=1001;
- For J:=0 To Total Do
- If (Zi[0][J]<>0) And (Zi[0][J]<Ps) Then
- Begin Ps:=Zi[0][J];K:=J;End;
- Assign(F,Fou);
- Rewrite(F);
- Writeln(F,Ps);
- Now[2]:=Use2[K,1];
- Now[3]:=Use2[K,2];
- Now[4]:=Use2[K,3];
- For I:=2 To 4 Do
- If Now[I]>=Shu[N] Then Inc(Now[I]);
- Now[1]:=Shu[N];
- Pr[N]:=1;
- For K:=N-1 Downto 1 Do {分阶段打印}
- Begin
- J:=1;
- While Now[J]<>Shu[K+1] Do
- Inc(J);
- W2:=0;
- For I:=1 To 4 Do
- If I<>J Then
- Begin
- Inc(W2);Q[W2]:=Now[I];
- If Q[W2]>=Shu[K+1] Then Dec(Q[W2]);
- End;
- W1:=Use1[Q[1],Q[2],Q[3]];
- Now[J]:=Ku[K+1]^[W1];
- For I:=1 To 4 Do
- If Now[I]=Shu[K] Then
- Pr[K]:=I;
- End;{End For K}
- J:=1;
- Pr1[1]:=Pr[1];
- For I:=2 To N1 Do
- Begin
- If Shu1[I]<>Shu1[I-1] Then Inc(J);
- Pr1[I]:=Pr[J];
- End;
- For I:=1 To N1 Do
- Write(F,Pr1[I],' ');
- Close(F);
- End;
- {Main} {主程序}
- Begin
- Init; {初始化}
- Diduse; {准备}
- Main; {动态规划过程}
- Print; {输出}
- End.
|