douyin LSY_HELLOWORLD,已成功入职互联网大厂,请关注我,了解非科班的程序员的工作生活把
题目来源 360春招2021编程题
所谓回文数就是一个数字,从左边读和从右边读的结果都是一样的,例如12321。
现在有一个只包含1、2、3、4的数字,你可以通过在任意位置增加一位数字或者删除一位数字来将其变换成一个回文数。但是增加或删除不同数字所需要的代价是不一样的。
已知增加和删除每个数字的代价如下:
增加一个1,代价:100;删除一个1,代价:120。
增加一个2,代价:200;删除一个2,代价:350。
增加一个3,代价:360;删除一个3,代价:200。
增加一个4,代价:220;删除一个4,代价:320。
请问如何通过最少的代价将一个数字变换为一个回文数。当然,如果一个数字本身已经是一个回文数(包括一位数,例如:2),那么变换的代价为0。
输入描述:
单组输入。
输入一个由1、2、3、4组成的正整数,正整数位数<=100位。【提示:采用字符串输入】
输出描述:
输出一个整数,表示将输入数字变换为一个回文数所需的最少代价。
输入例子1:
12322
输出例子1:
300
例子说明1:
增加一个1并增加一个2,将输入正整数变为1223221或者2123212,所需代价最小,为:100+200=300。
package main
import (
"fmt"
)
func main() {
add := []int{0, 100, 200, 360, 220} //增加的代价
del := []int{0, 120, 350, 200, 320} //删除的代价
ss := ""
fmt.Scan(&ss)
n := len(ss)
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n)
}
var dfs func(l, r int) int
dfs = func(l, r int) int {
if r <= l {
return 0
}
if dp[l][r] == 0 {
if ss[l] == ss[r] {
dp[l][r] = dfs(l+1, r-1)
} else {
dp[l][r] = min(min(dfs(l+1, r)+add[ss[l]-'0'], dfs(l+1, r)+del[ss[l]-'0']), min(dfs(l, r-1)+add[ss[r]-'0'], dfs(l, r-1)+del[ss[r]-'0']))
}
}
return dp[l][r]
}
fmt.Println(dfs(0, n-1))
}
func min(x, y int) int {
if x < y {
return x
}
return y
}