Many places in this topic hint at the DP path.
When we deal with it, dp[i][j] can be considered as the minimum cost to the palindrome effect from the i-coordinate to the J-coordinate sequence, which expands outward, and finally gets dp[0][m-1] is the result.
We need to be aware of the results of DP (I+1,J-1) when dealing with dp[i][j], so I must be in descending order and J must be ascending in order to ensure that the calculated results are available when DP (I,J) is calculated.
So
I should decrement from M-2 to 0
J increments from I+1 to M-1 in the inner layer
When dealing with DP (I,J), the first thing to see is name[i] and name[j] is equal, if equal, then directly inward one layer can be
DP[I][J] = dp[i+1][j-1]
Otherwise we are going to transform it into a palindrome string
There are four ways to change this.
1. First let i+1 to J is a palindrome and then add a name[i at the end]
2. First let the i+1 to J is a palindrome and then the front of the name[i] deleted
3. First let I to J-1 is a palindrome and then in the front plus a name[j]
4. First let I to J-1 is palindrome and then in the last Name[j] Delete
Choose a scheme that consumes the least amount.
The code is as follows
#include <iostream>#include<cstring>using namespacestd;structchr{CharC; intadd; intdel;}; CHR v[ -];intn,m;stringname;voidinit () {cin>>N>>l; //N is the number of different letters//m is the length of the original nameCin>>name; //record The cost of the letter for(inti =0; i < N; ++i) {CharC; CIN>>C; V[c-'a'].C =C; CIN>>v[c-'a'].add >> v[c-'a'].del; }}unsignedLong Longdp[2500][2500]={0};//storage is a palindrome minimum consumption from the letter I to the J letterintbuild () {//fill dp[i][j from back to front] for(inti = m2; I >=0; --i) { for(intj = i +1; J < M; ++j) { if(name[i]==Name[j]) dp[i][j]= dp[i+1][j-1];//If I and J are the same, buckle one without any action . Else{ //if not, consider four methods of modificationDP[I][J] =1<< -; unsignedLong Longcs[4]; //notice at this point to ensure that both i+1,j and i,j-1 are complete, so select I descending J ascendingcs[0] = dp[i+1][J] + v[name[i]-'a'].add;//first let I+1 to J is a palindrome and then at the end add a ics[1] = dp[i+1][J] + v[name[i]-'a'].del;//first let the i+1 to J is a palindrome and then delete the front Ics[2] = dp[i][j-1] + v[name[j]-'a'].add;//first let I to J-1 is a palindrome and then at the front plus a Jcs[3] = dp[i][j-1] + v[name[j]-'a'].del;//first let I to J-1 is palindrome again in the last J delete for(intK =0; k<4; ++k) Dp[i][j]=min (dp[i][j],cs[k]); } } } returndp[0][m-1];}intMainintargcChar Const*argv[]) {init (); cout<<build () <<Endl; return 0;}
Algorithm Learning note 70. Dynamic planning of Palindrome sequence SJTU OJ 1066 small m family of cows