题目描述:
小明有一个长度为n,由前k个小写英文字母组成的字符串(保证n为偶数)。
小明花费1个硬币可以将他相邻的这两个字母构成的字符消除。小明每次可以选择该串中的两个相邻的字符相同,删除后将硬币丢掉,并花费小明一段一定数量的零钱。
若某一对删除的相邻两个字符分别是a和b,则将花掉小明cost(a, b)块钱。小明希望他花掉的零花钱尽可能少,帮帮小明。
输入描述:
第一行有两个整数n, k(1<=n<=500,1<=k<=26),分别代表小明的字符串长度与字符中的字符种类数(保证n为偶数且串的内容仅由前k个小写英文字母组成)。
接下来k行给出了一个k*k的整数构成的矩阵。矩阵中第i行第j列的元素代表删除相邻的第i个字母和第j个字母所能花掉的块数。
最后一行有一个长度为n的字符串,代表小明的字符串。
输出描述:
输出一个值,代表小明最少能花掉多少零花钱。
package com.sky;
import java.util.Scanner;
public class Test1 {
static long[][] f = new long[27][27];
static long[][] dp = new long[510][510];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
for (int i = 0; i < k; i++) {
for (int j = 0; j < k; j++) {
f[i][j] = sc.nextLong();
}
}
String s = sc.next();
s = " " + s;
for (int len = 2; len <= n; len++) {
for (int l = 1; l + len - 1 <= n; l++) {
int r = l + len - 1;
dp[l][r] = dp[l + 1][r - 1] + f[s.charAt(l) - 'a'][s.charAt(r) - 'a'];
dp[l][r] = Math.max(dp[l][r], dp[l][r - 2] + f[s.charAt(r - 1) - 'a'][s.charAt(r) - 'a']);
dp[l][r] = Math.max(dp[l][r], dp[l + 2][r] + f[s.charAt(l) - 'a'][s.charAt(l + 1) - 'a']);
for (int j = l + 1; j + 1 <= r; j += 2) {
dp[l][r] = Math.max(dp[l][j] + dp[j + 1][r], dp[l][r]);
}
}
}
System.out.println(dp[1][n]);
sc.close();
}
}