2021-12-17:长城守卫军问题。 长城上有连成一排的n个烽火台,每个烽火台都有士兵驻守。 第i个烽火台驻守着ai个士兵,相邻峰火台的距离为1。另外,有m位将军, 每位将军可以驻守一个峰火台,每个

2021-12-17:长城守卫军问题。 长城上有连成一排的n个烽火台,每个烽火台都有士兵驻守。 第i个烽火台驻守着ai个士兵,相邻峰火台的距离为1。另外,有m位将军, 每位将军可以驻守一个峰火台,每个,第1张

2021-12-17:长城守卫军问题。 长城上有连成一排的n个烽火台,每个烽火台都有士兵驻守。 第i个烽火台驻守着ai个士兵,相邻峰火台的距离为1。另外,有m位将军, 每位将军可以驻守一个峰火台,每个

2021-12-17:长城守卫军问题。
长城上有连成一排的n个烽火台,每个烽火台都有士兵驻守。
第i个烽火台驻守着ai个士兵,相邻峰火台的距离为1。另外,有m位将军,
每位将军可以驻守一个峰火台,每个烽火台可以有多个将军驻守,
将军可以影响所有距离他驻守的峰火台小于等于x的烽火台。
每个烽火台的基础战斗力为士兵数,另外,每个能影响此烽火台的将军都能使这个烽火台的战斗力提升k。
长城的战斗力为所有烽火台的战斗力的最小值。
请问长城的最大战斗力可以是多少?
输入描述
第一行四个正整数n,m,x,k(1<=x<=n<=105,0<=m<=105,1<=k<=10^5)
第二行n个整数ai(0<=ai<=10^5)
输出描述 仅一行,一个整数,表示长城的最大战斗力
样例输入
5 2 1 2
4 4 2 4 4
样例输出
6
来自360。

答案2021-12-17:

这道题很难。
从业务里找限制。
1.二分答案。
2.类似于AOE贪心。
3.线段树。
时间复杂度:未知。
空间复杂度:未知。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
	wall := []int{3, 1, 1, 1, 3}
	m := 2
	x := 3
	k := 1
	fmt.Println(maxForce(wall, m, x, k))
}

func maxForce(wall []int, m, x, k int) int {
	L := 0
	R := 0
	for _, num := range wall {
		if num > R {
			R = num
		}
	}
	R += m * k
	ans := 0
	for L <= R {
		M := (L + R) / 2
		if can(wall, m, x, k, M) {
			ans = M
			L = M + 1
		} else {
			R = M - 1
		}
	}
	return ans
}

func can(wall []int, m, x, k, limit int) bool {
	N := len(wall)
	// 注意:下标从1开始
	st := NewSegmentTree(wall)
	st.build(1, N, 1)
	need := 0
	for i := 0; i < N; i++ {
		// 注意:下标从1开始
		cur := st.query(i+1, i+1, 1, N, 1)
		if cur < limit {
			add := (limit - cur + k - 1) / k
			need += add
			if need > m {
				return false
			}
			st.add(i+1, getMin(i+x, N), add*k, 1, N, 1)
		}
	}
	return true
}

func getMin(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

type SegmentTree struct {
	MAXN    int
	arr     []int
	sum     []int
	lazy    []int
	change  []int
	update0 []bool
}

func NewSegmentTree(origin []int) *SegmentTree {
	ret := &SegmentTree{}
	ret.MAXN = len(origin) + 1
	ret.arr = make([]int, ret.MAXN)
	for i := 1; i < ret.MAXN; i++ {
		ret.arr[i] = origin[i-1]
	}
	ret.sum = make([]int, ret.MAXN<<2)
	ret.lazy = make([]int, ret.MAXN<<2)
	ret.change = make([]int, ret.MAXN<<2)
	ret.update0 = make([]bool, ret.MAXN<<2)
	return ret
}

func (this *SegmentTree) pushUp(rt int) {
	this.sum[rt] = this.sum[rt<<1] + this.sum[rt<<1|1]
}

func (this *SegmentTree) pushDown(rt, ln, rn int) {
	if this.update0[rt] {
		this.update0[rt<<1] = true
		this.update0[rt<<1|1] = true
		this.change[rt<<1] = this.change[rt]
		this.change[rt<<1|1] = this.change[rt]
		this.lazy[rt<<1] = 0
		this.lazy[rt<<1|1] = 0
		this.sum[rt<<1] = this.change[rt] * ln
		this.sum[rt<<1|1] = this.change[rt] * rn
		this.update0[rt] = false
	}
	if this.lazy[rt] != 0 {
		this.lazy[rt<<1] += this.lazy[rt]
		this.sum[rt<<1] += this.lazy[rt] * ln
		this.lazy[rt<<1|1] += this.lazy[rt]
		this.sum[rt<<1|1] += this.lazy[rt] * rn
		this.lazy[rt] = 0
	}
}

func (this *SegmentTree) build(l, r, rt int) {
	if l == r {
		this.sum[rt] = this.arr[l]
		return
	}
	mid := (l + r) >> 1
	this.build(l, mid, rt<<1)
	this.build(mid+1, r, rt<<1|1)
	this.pushUp(rt)
}

func (this *SegmentTree) update(L, R, C, l, r, rt int) {
	if L <= l && r <= R {
		this.update0[rt] = true
		this.change[rt] = C
		this.sum[rt] = C * (r - l + 1)
		this.lazy[rt] = 0
		return
	}
	mid := (l + r) >> 1
	this.pushDown(rt, mid-l+1, r-mid)
	if L <= mid {
		this.update(L, R, C, l, mid, rt<<1)
	}
	if R > mid {
		this.update(L, R, C, mid+1, r, rt<<1|1)
	}
	this.pushUp(rt)
}

func (this *SegmentTree) add(L, R, C, l, r, rt int) {
	if L <= l && r <= R {
		this.sum[rt] += C * (r - l + 1)
		this.lazy[rt] += C
		return
	}
	mid := (l + r) >> 1
	this.pushDown(rt, mid-l+1, r-mid)
	if L <= mid {
		this.add(L, R, C, l, mid, rt<<1)
	}
	if R > mid {
		this.add(L, R, C, mid+1, r, rt<<1|1)
	}
	this.pushUp(rt)
}

func (this *SegmentTree) query(L, R, l, r, rt int) int {
	if L <= l && r <= R {
		return this.sum[rt]
	}
	mid := (l + r) >> 1
	this.pushDown(rt, mid-l+1, r-mid)
	ans := 0
	if L <= mid {
		ans += this.query(L, R, l, mid, rt<<1)
	}
	if R > mid {
		ans += this.query(L, R, mid+1, r, rt<<1|1)
	}
	return ans
}

执行结果如下:


左神java代码

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5677567.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存