26. 内积
给定长度为NN的AA数组,长度为KK的BB数组
你可以从AA数组里取KK个数
规则如下:
-
每个
A_i
A
i
只能被取出一次
-
i==1 \quad or \quad i==Ni==1ori==N 可以直接取出
A_i\quad
A
i
-
2 \leq i \leq N-1\quad2≤i≤N−1 若
A_{i-1}
A
i−1
或者
A_{i+1}
A
i+1
已经取出,则可以取出
A_i
A
i
-
要取出正好KK个数
即每次可以从AA数组的最左边或者最右边取走一个数,取走的数从数组中移除
将取出的
A_i
A
i
按取出的顺序 组成CC数组
求BB与CC的内积最大值
BB与CC内积为
\sum_{i=0}^{K-1}B_i \times C_i
∑
i=0
K−1
B
i
×
C
i
解释1:
AA= [1,4,3,2,5]
BB=[1,2,3,4]
KK=4
取出
A_0
A
0
,CC=[1]
取出
A_4
A
4
CC=[1,5]
取出
A_1
A
1
CC=[1,5,4]
取出
A_2
A
2
CC=[1,5,4,3]
BB·CC=1*1+2*5+3*4+4*3=35
这只是CC的一种可行方案,可能不是最优方案
解释2
AA=[1,2,3,4]
不能直接取出
A_1
A
1
因为
A_0
A
0
和
A_2
A
2
都没有取出
样例
[2,3,5,1]
[2,1]
取出
A_0,A_1
A
0
,
A
1
注意事项
1 \leq K \leq N \leq 20001≤K≤N≤2000
1 \leq A_i,B_i \leq 100000
1≤
A
i
,
B
i
≤100000
public class Solution {
long[][] dp;
public long getMaxInnerProduct(int[] A, int[] B) {
int len1 = A.length;
int len2 = B.length;
dp = new long[len2 + 1][len2 + 1];
for (int i = 0; i <= len2; i++) {
for (int j = 0; j <= len2; j++) {
if (i == 0 && j == 0) continue;
if (i + j > len2) continue;
if (i + j > len1) continue;
if (i == 0) dp[i][j] = dp[i][j - 1] + (long)A[len1 - j] * B[i + j - 1];
else if (j == 0) dp[i][j] = dp[i - 1][j] + (long)A[i - 1] * B[i + j - 1];
else dp[i][j] = Math.max(dp[i - 1][j] + (long)A[i - 1] * B[i + j - 1], dp[i][j - 1] + (long)A[len1 - j] * B[i + j - 1]);
}
}
long res = 0;
for (int i = 0; i <= len2; i++) res = Math.max(res, dp[i][len2 - i]);
return res;
}
}
超时
public class Solution {
/**
* @param A: the A array
* @param B: the B array
* @return: return the maxium inner product of B and C
*/
public long getMaxInnerProduct(int[] A, int[] B) {
int start = 0, end = A.length - 1;
helper(A,B,0,0,end,0);
return max;
}
long max = 0;
private void helper(int[] a, int[] b, int i, int start, int end, long sum) {
if (i>=b.length){
System.out.println(sum);
max=Math.max(max,sum);
return;
}
helper(a,b,i+1,start+1,end, sum+b[i]*a[start]);
helper(a,b,i+1,start,end-1,sum+b[i]*a[end]);
}
}