1.更改石子游戏模板并解析边界值(java代码)
//石子游戏模板代码
for(int len = 2;len<=n;len++) //枚举长度
for(int l = 1;l+len-1<=n;l++){
int r = l+len -1;
dp[l,r] = INF;
for(int k = l;k<r;++k) dp[l,r] = min(dp[l,r],dp[l,k]+dp[k+1,r]+sum[l,r]);
}
看了很多的题解,发现有些解答边界值是像下面这个代码,
dp[i][i] = a[i]*b[n];
}
但是不解释具体为什么是a[i]*b[n],为什么不是a[i]*b[i]或者是其他的下面我来给大家一步一步推导. 假设dp[1,n]是1-n的最小代价那么肯定是如下关系 dp[1,n] = max{dp[1,n-1]+a[n]*b[1].dp[2,n]+a[1]*b[1]} 有的同学可能会疑惑,为什么不是b[n]而是b[1]。是这样的,a[1]和a[n]两个位置其中之一只能在第一次去取,对应的第一次代价就是b[1],所以乘的是b[1]而不是b[n] 而dp[1,n-1] = max{dp[2,n-1]+a[1]*b[2],dp[1,n-2] + a[n-1]*b[2]} dp[2,n] = max{dp[2,n-1]+a[n]*b[2],dp[3,n] + a[2]*b[2]} 以此类推b里面的数字 = n-(j-i)=n-(len-1) 当j=i时,b里面的数字=n dp[i][i] = a[i]*b[n] java代码如下
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int t = input.nextInt();
while (t-->0){
int n = input.nextInt();
int[] a = new int[n+2];
int[] b = new int[n+2];
for (int i = 1; i <=n ; i++) {
a[i] = input.nextInt();
}
for (int i = 1; i <=n ; i++) {
b[i] = input.nextInt();
}
int[][] dp = new int[n+2][n+2];
for(int i=1;i<=n;i++){
dp[i][i] = a[i]*b[n];
}
for(int len=2;len<=n;len++)
{
for(int l = 1; l+len-1<=n; l++)
{
int r = l+len-1;
dp[l][r] = Math.max(dp[l+1][r] + a[l]*b[n-len+1],
dp[l][r-1]+a[r]*b[n-len+1]);
}
}
System.out.println(dp[1][n]);
}
}
}