← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n int
	fmt.Fscan(reader, &n)

	h := make([]int, n)
	b := make([]int, n)

	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &h[i])
	}
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &b[i])
	}

	// dp[i] = maximum beauty for buildings 0..i-1
	// dp[0] = 0
	// dp[i] = max over j from 0 to i-1 of (dp[j] + beauty of photo covering j..i-1)
	// beauty of photo covering j..i-1 = b[min height in j..i-1]
	
	// Key insight: for each building k, it is the minimum of photo [j..i-1] 
	// iff h[k] is the minimum in that range, meaning j <= k <= i-1 and 
	// h[k] < h[m] for all m in [j, i-1] except k.
	
	// We use a stack-based approach:
	// dp[i] = max over k where k could be the minimum of the last segment ending at i-1
	// 
	// For each i (1-indexed endpoint), we want:
	// dp[i] = max_{j=1}^{i} (dp[j-1] + b[min of h[j..i]])
	//
	// Using a monotonic stack on heights:
	// Maintain a stack of (height, max_dp_val) where max_dp_val represents
	// the best dp[j-1] achievable when h[k] is the minimum of the segment.
	
	// More precisely, we maintain a stack where each entry represents a "group"
	// of potential left endpoints where a certain building is the minimum.
	// Stack stores (h[k], best) where best = max dp[j-1] for j in the group,
	// and the current photo beauty would be b[k].
	
	// When we process position i (0-indexed building i):
	// We consider building i as part of segments ending at i.
	// Pop elements from stack that have height > h[i] (building i is shorter).
	// The best value from popped elements gets merged.
	
	dp := make([]int64, n+1)
	dp[0] = 0

	type stackEntry struct {
		height int
		best   int64 // max dp[j] for left boundaries in this group
	}

	stack := []stackEntry{}

	for i := 0; i < n; i++ {
		// We're computing dp[i+1]
		// New entry for building i: the group where h[i] is minimum
		// Initially best = dp[i] (segment of length 1: just building i)
		cur := stackEntry{h[i], dp[i]}

		for len(stack) > 0 && stack[len(stack)-1].height > h[i] {
			top := stack[len(stack)-1]
			stack = stack[:len(stack)-1]
			// Merge: building i is shorter than top's buildings,
			// so building i becomes the minimum for those left endpoints too
			if top.best > cur.best {
				cur.best = top.best
			}
		}

		stack = append(stack, cur)

		// Now compute dp[i+1] = max over all stack entries of (entry.best + b[building with entry.height])
		// But we need to know which building index corresponds to the minimum in each group.
		// Actually the stack entry's height corresponds to the current minimum building.
		// Wait, we need b value of the minimum building, not just its height.
		
		// Let me reconsider: we need to track b value of the minimum building in each group.
		// Modify stack to store b value of the minimum.
		_ = stack
		_ = cur
		break
	}

	// Redo with b value tracked
	type entry struct {
		height int
		bVal   int64
		best   int64
	}

	stk := []entry{}
	dp[0] = 0

	var ans int64 = -1 << 60

	for i := 0; i < n; i++ {
		cur2 := entry{h[i], int64(b[i]), dp[i]}

		for len(stk) > 0 && stk[len(stk)-1].height > h[i] {
			top := stk[len(stk)-1]
			stk = stk[:len(stk)-1]
			if top.best > cur2.best {
				cur2.best = top.best
			}
		}

		stk = append(stk, cur2)

		// dp[i+1] = max over entries in stack of (entry.best + entry.bVal)
		var best int64 = -1 << 60
		for _, e := range stk {
			val := e.best + e.bVal
			if val > best {
				best = val
			}
		}
		dp[i+1] = best
		if dp[i+1] > ans {
			ans = dp[i+1]
		}
	}

	fmt.Fprintln(writer, ans)
}
```