1、剪绳子
给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1,m>1), 每段绳子的长度记为 k[0], k[1], k[2], …, k[m]。 请问 k[0] * k[1] * k[2] * … * k[m] 可能的最大乘积是多少? 例如,当绳子的长度为8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
解法一:动态规划
func max(a int,b int) int{
if a>=b {
return a
}else {
return b
}
}
func main(){
var N int
fmt.Scan(&N)
f := make([]int,N+1)
for i:=1;i<=3;i++ {
f[i]=i
}
for n:=2;n<=N;n++ {
for i:=1;i<n;i++{
f[n]=max(f[n],f[n-i]*f[i])
}
}
fmt.Println(f[N])
}
解法二:贪心算法
func main(){
var N,res int
fmt.Scan(&N)
m := float64(N/3)
c := N%3
if c == 1 {
m-=1
res = int(math.Pow(3,m)*4)
}else if c==2 {
res = int(math.Pow(3,m)*2)
}else {
res = int(math.Pow(3,m))
}
fmt.Println(res)
}
2、剪绳子加强版
给你一根长度为n的绳子,要求剪成m段,(上面剪成几段都可以,这里m给出)(m、n都是整数,n>1,m>1), 每段绳子的长度记为 k[0], k[1], k[2], …, k[m]。 请问 k[0] * k[1] * k[2] * … * k[m] 可能的最大乘积是多少? 例如,当绳子的长度为8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
func max(a int,b int) int{
if a>=b {
return a
}else {
return b
}
}
func main(){
var N,M int
fmt.Scan(&N,&M)
var f [][]int
for i:=0;i<=N;i++ {
temp := make([]int,M+1)
f = append(f,temp)
}
for i:=1;i<=N-M+1;i++ {
f[i][1]=i
}
fmt.Println(f)
for j:=2;j<=M;j++{ //截成j段
for i:=j;i-j<=N-M;i++{//木棍长度
f[i][j]=f[i-1][j-1]
for k:=1;i-k>=j;k++ {
f[i][j] = max(f[i-k][j-1]*k,f[i][j])
}
}
}
fmt.Println(f[N][M])
}
3、【题目描述】魔法石矿(Mine.cpp/c/pas)
每个矿里有一定数量的魔法石,同时每个矿中都有一张说明书,说明在挖完此矿的魔法石后还可继续挖哪些矿,挖矿规则为可以从任何一个矿开始,到任何一个矿结束,同时挖完这个矿中的魔法石之后,可以选择它可继续挖的矿之一继续挖,但只能选择一条。如挖完1矿后,可挖2矿,再挖5矿,6矿,……但只可以向右挖,不能回头向左挖。请问如何挖才能挖出最多的魔法石?
【输入格式】
第一行为一个整数n,表示有n(n≤1000)个矿。第二行为n个整数,表示这n个矿的魔法石数。随后n行表示每个矿挖完后还能再挖哪些矿。
【输出格式
最多挖出的魔法石数。
【输入样例】
3
1 1 1
1 2 3
2 3
3
【输出样例】
3
方法一:
type Node struct {
Max int //以该矿结束可以取的最大值
PreLink int //上一个矿
Lis []int //link存每个矿挖完后还能再挖那些矿。
W int //每个矿的值
}
func isNumber(c byte) bool {
if c >= '0' && c <= '9' {
return true
} else {
return false
}
}
func main(){
var N,i,j int
var node []Node
tempNode := Node{}
fmt.Scan(&N)
for i=0;i<N;i++ {
fmt.Scan(&tempNode.W)
tempNode.Max = tempNode.W
tempNode.PreLink = i
node = append(node,tempNode)
}
var c byte
for i=0;i<N;i++ {
for {
fmt.Scanf("%c", &c)
if isNumber(c) {
l := int(c-'0')-1
node[i].Lis = append(node[i].Lis, l)
}
if c == '\n' {
break
}
}
}
for i=0;i<N;i++ {
fmt.Println(node[i])
}
for i=0;i<N;i++ {
for j=1;j<len(node[i].Lis);j++ {
linkT := node[i].Lis[j]
if node[linkT].Max < node[i].Max + node[linkT].W {
node[linkT].Max = node[i].Max + node[linkT].W
node[linkT].PreLink = i
}
}
}
max := 0
linkM := 0
for i=0;i<N;i++ {
if node[i].Max > max {
max = node[i].Max
linkM = i
}
}
fmt.Println("MAX:",max)
for node[linkM].PreLink != linkM {
fmt.Print(linkM,"<-")
linkM = node[linkM].PreLink
}
fmt.Print(linkM)
}
方法二:
/* for i=0;i<N;i++ {
for j=len(node[i].Lis)-2;j>=0;j-- {
linkT := node[i].Lis[j]
if node[i].Max < node[linkT].Max + node[i].W {
node[i].Max = node[linkT].Max + node[i].W
node[i].PreLink = linkT
}
}
}*/