#37788: 解題思路(含一些小技巧)


edoctopus322@gmail.com (Moon Jam)

學校 : 臺北市立成功高級中學
編號 : 167591
來源 : [36.225.19.60]
最後登入時間 :
2023-12-23 13:47:18
i402. 4. 內積 -- 2022年6月APCS | From: [36.225.24.5] | 發表日期 : 2023-10-08 12:07

 
解題思路:
這題我的做法是使用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]的最大值。
 
ZeroJudge Forum