SRM306 div2 difficult
貪欲法で解けそうだけど、
oldText:aaaa newText:abacacaaaa とかのときはだめになる. //貪欲法:4 a[b]a[c]a[c]a[aaa] 本当の答え:1 a[bacacacaa]aaa
典型的な動的計画法。
int minDist(vectoroldText, vector newText) { string oldT = ""; string newT = ""; for(int i = 0, sz = oldText.size(); i < sz; i++) { oldT += oldText[i]; } for(int i = 0, sz = newText.size(); i < sz; i++) { newT += newText[i]; } int newLen = newT.length(); int oldLen = oldT.length(); fill(dp[0], dp[0]+1001*1001, INF); //EQUAL TO [int minDist(string oldT, string newT)] //trigger for(int i = 0; i < newLen; i++) { if(oldT[0] == newT[i]) { dp[0][i] = 1; } } if(dp[0][0] == 1) dp[0][0] = 0; //Dynamic Programming START!! for(int i = 1; i < oldLen; i++) { //j++にすると、何回も書き換えられる可能性がある. for(int j = newLen-1; j >= i; j--) { if(oldT[i] == newT[j]) { for(int k = j-1; k >= 0; k--) { int isAdjacent = (k == j-1) ? 0 : 1; if(dp[i-1][k] != INF) { dp[i][j] = min(dp[i][j], dp[i-1][k]+isAdjacent); } } } //if end } } //for i for(int i = 0; i < newLen-1; i++) { if(dp[oldLen-1][i] != INF) { dp[oldLen-1][i]++; } } int ans = *min_element(dp[oldLen-1], dp[oldLen-1]+newLen); return ans == INF ? -1 : ans; }
二重ループにするとこんな感じになるのかな.
int minDist(vector <string> oldText, vector <string> newText) { string oldT = ""; string newT = ""; for(int i = 0, sz = oldText.size(); i < sz; i++) { oldT += oldText[i]; } for(int i = 0, sz = newText.size(); i < sz; i++) { newT += newText[i]; } int newLen = newT.length(); int oldLen = oldT.length(); fill(dp[0], dp[0]+1001*1001, INF); //minDist(string oldT, string newT) //trigger for(int i = 0; i < newLen; i++) { dp[0][i] = 1; } if(dp[0][0] == 1) dp[0][0] = 0; for(int i = 0; i < oldLen; i++) { int mini = INF; for(int j = i; j < newLen; j++) { if(oldT[i] == newT[j]) { dp[i+1][j+1] = dp[i][j]; mini = min(dp[i+1][j+1], mini); } else { if(mini != INF) { dp[i+1][j+1] = mini+1; } } // end if } } return dp[oldLen][newLen] == INF ? -1 : dp[oldLen][newLen]; }