這題我的做法是使用DP,給定dp[i][j]為a[i]與b[j]往後直到其中一個底端的區間內任意r值最大內積,可以知道當r=1時,dp[i][j] = a[i]*b[j],而對於n-i>1 且 m-j>1的狀態轉移就會是:
dp[i][j]=max(a[i]*b[j], dp[i+1][j+1], pre[i+1][j+1]+a[i]*b[j])
其中pre[i][j] 代表以a[i]與b[j]為開頭的最大內積前綴和,由此應該就能很清楚的理解轉移式的意義,a[i]與b[j]後的最大內積,只有可能是a[i+1]跟b[i+1]為開頭的最大內積、a[i]跟b[j]為開頭的最大內積前綴和加上a[i]*b[j]的內積或是自己本身a[i]*b[j]。
🌟 在翻轉的部分只要將其中一個陣列翻轉過來即可,因為不論是正向還是反向,兩個陣列的內積都是一樣的,因此只要將其中一個陣列翻轉過來,再做一次正向的內積即可。
❗️ dp[0][0]不一定會是整個陣列的最大值,因為n、m可能不一樣大,dp[i][j]的定義是a[i]與b[j],往後直到其中一個底端的區間內任意r值最大內積,因此若其中一個先碰到了底端,但事實上另一個陣列跟其他段內積會更大的話,就會使得dp[0][0]不是最大值,因此較簡單的方法是在做狀態轉移時,將用一個變數紀錄dp[i][j]的最大值。