LeetCode 1320. The second refers to the minimum distance of input -- Dynamic Programming -- interval DP

  1. The second refers to the minimum distance entered

The layout of the two finger input method customized keyboard on the XY plane is shown in the above figure, in which each uppercase English letter is located at a certain coordinate, for example, the letter A is located at the coordinate (0,0), the letter B is located at the coordinate (0,1), the letter P is located at the coordinate (2,3) and the letter Z is located at the coordinate (4,1).

Give you a string word to be input. Please calculate and return the minimum total distance to move the string when only two fingers are used. The distance between coordinates (x1,y1) and (x2,y2) is | x1 - x2| + |y1 - y2 |.

Note that the starting position of the two fingers is zero cost and is not included in the total moving distance. Your two fingers don't have to start with the first letter or the first two letters.

Example 1:

Input: word = "CAKE"
Output: 3
Explanation:
One of the best ways to enter "CAKE" with two fingers is:
Finger 1 on letter 'C' - > moving distance = 0
Finger 1 on letter 'A' > > moving distance = distance from letter 'C' to letter 'A' = 2
Finger 2 on letter 'K' - > moving distance = 0
Finger 2 on letter 'E' - > moving distance = distance from letter 'K' to letter 'E' = 1
Total distance = 3

Example 2:

Input: word = "HAPPY"
Output: 6
Explanation:
One of the best ways to enter "HAPPY" with two fingers is:
Finger 1 on letter 'H' - > moving distance = 0
Finger 1 on letter 'A' - > moving distance = distance from letter 'H' to letter 'A' = 2
Finger 2 on letter 'P' - > moving distance = 0
Finger 2 on letter 'P' - > moving distance = distance from letter 'P' to letter 'P' = 0
Finger 1 on letter 'Y' - > moving distance = distance from letter 'A' to letter 'Y' = 4
Total distance = 6

Example 3:

Input: word = "NEW"
Output: 3

Example 4:

Input: word = "YEAR"
Output: 7

Tips:

2 <= word.length <= 300
 each word[i] Is a capital English letter.

Problem solution

At first, I was wrong. At first, I thought that dp[maxn][2], dp[i][0] meant the first finger for the i-th letter, and dp[i][1] meant the second finger for the i-th letter. However, it was found that it could not be updated and the state could not be transferred. After repeated thinking, it reached the interval dp.

If only one finger is used, the answer is unique. The key point is that two fingers are the most complex. We don't know how to deal with it. We define dp[maxn][maxn], and dp[i][j] represents the minimum distance when two fingers stay in the ith letter and the j letter respectively. Therefore, we get the state transition relationship as follows:

if j>i+1:
Then only dp[i][j] = min(dp[i][j],dp[i][j-1] + distance(word[j-1],word[j])
else if j == i+1:
There are two cases. One is to find a suitable K in dp[k][i], the value range of K is [1,i-1], and the update process is:
dp[i][j] = min(dp[i][j],dp[k][i] + distance(word[k],word[j]))
Or, only one finger is used up to the i position, and then the second finger suddenly appears at the j letter. The update process is as follows:
dp[i][j] = min(dp[i][j],dp[i][i])

Here we think that dp[i][i] is the distance from the i-th letter position with only one finger.

AC code

class Solution {
public:
    int XX[30],YY[30];
    int get_distance(char a,char b)
    {
        return abs(XX[a-'A']-XX[b-'A']) + abs(YY[a-'A']-YY[b-'A']);
    }
    int dp[305][305];
    int minimumDistance(string word) 
    {
        for(int i=0;i<26;i++)
        {
            XX[i] = i/6;
            YY[i] = i%6;
        }
        memset(dp,0x3f3f3f,sizeof(dp));
        for(int i=0;i<=2;i++)
        {
            for(int j=0;j<=2;j++)
            dp[i][j] = 0;
        }
        for(int i=2;i<=word.length();i++)
        {
            dp[i][i] = get_distance(word[i-1],word[i-2]) + dp[i-1][i-1];
        }
        for(int i=1;i<=word.length();i++)
        {
            for(int j=i+1;j<=word.length();j++)
            {
                if(j>i+1)
                {
                    dp[i][j] = dp[i][j-1] + get_distance(word[j-2],word[j-1]);
                }
                else if(j==i+1)
                {
                    for(int k=1;k<i;k++)
                    {
                        dp[i][j] = min(dp[i][j],dp[k][i]+get_distance(word[k-1],word[j-1]));
                    }
                    dp[i][j] = min(dp[i][j],dp[i][i]);
                }
                //cout<<i<<" "<<j<<" "<<dp[i][j]<<endl;
            }
        }
        int mi = 1e9;
        for(int i=1;i<=word.length();i++)
        mi = min(mi,dp[i][word.length()]);
        return mi;
    }
};

Tags: leetcode AI Dynamic Programming

Posted on Fri, 26 Nov 2021 17:24:01 -0500 by mmorton