Skip to content

Commit

Permalink
aaa
Browse files Browse the repository at this point in the history
  • Loading branch information
WangSenyuan committed Jun 2, 2024
1 parent caa4519 commit 3d4717b
Show file tree
Hide file tree
Showing 13 changed files with 779 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/codeforces/set1/set19/set191/set1912/a/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Allyn is playing a new strategy game called "Accumulator Apex". In this game, Allyn is given the initial value of an integer 𝑥
, referred to as the accumulator, and 𝑘
lists of integers. Allyn can make multiple turns. On each turn, Allyn can withdraw the leftmost element from any non-empty list and add it to the accumulator 𝑥
if the resulting 𝑥
is non-negative. Allyn can end the game at any moment. The goal of the game is to get the largest possible value of the accumulator 𝑥
. Please help Allyn find the largest possible value of the accumulator 𝑥
they can get in this game.

### ideas
1. max prefix sum?
2. 还有个要求,是在任何一步操作后,都不能出现负数
3. 那这样子就有难度了
4. max prefix sum还有用吗?
5. 如果任何一个队列的head是正数,直接加上去就可了
6. ok,现在所有的队列head都是负数,那似乎也应该加上绝对值最小的负数
7. 好像这个策略是ok的?
8. 不对的。可以考虑这样一个情况,就是 [-2, -3, 6], [-1, -2]
9. 假设现在x = 5, 如果只使用第一个list,那么收益 = 6, 但是如果使用上面的算法,把-1加入后,就无法达到收益6
10. 所以这里还有一个因素要考虑,就是在保证当前,且保证x >= 0 的前提下,可以得到的最大收益
11.
174 changes: 174 additions & 0 deletions src/codeforces/set1/set19/set191/set1912/a/solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package main

import (
"bufio"
"container/heap"
"fmt"
"os"
)

func main() {
reader := bufio.NewReader(os.Stdin)

x, n := readTwoNums(reader)
lists := make([][]int, n)

for i := 0; i < n; i++ {
s, _ := reader.ReadBytes('\n')
var m int
pos := readInt(s, 0, &m) + 1
lists[i] = make([]int, m)
for j := 0; j < m; j++ {
pos = readInt(s, pos, &lists[i][j]) + 1
}
}

res := solve(x, lists)

fmt.Println(res)
}

func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString('\n')
for i := 0; i < len(s); i++ {
if s[i] == '\n' || s[i] == '\r' {
return s[:i]
}
}
return s
}

func readInt(bytes []byte, from int, val *int) int {
i := from
sign := 1
if bytes[i] == '-' {
sign = -1
i++
}
tmp := 0
for i < len(bytes) && bytes[i] >= '0' && bytes[i] <= '9' {
tmp = tmp*10 + int(bytes[i]-'0')
i++
}
*val = tmp * sign
return i
}

func readNum(reader *bufio.Reader) (a int) {
bs, _ := reader.ReadBytes('\n')
readInt(bs, 0, &a)
return
}

func readTwoNums(reader *bufio.Reader) (a int, b int) {
res := readNNums(reader, 2)
a, b = res[0], res[1]
return
}

func readThreeNums(reader *bufio.Reader) (a int, b int, c int) {
res := readNNums(reader, 3)
a, b, c = res[0], res[1], res[2]
return
}

func readNNums(reader *bufio.Reader, n int) []int {
res := make([]int, n)
x := 0
bs, _ := reader.ReadBytes('\n')
for i := 0; i < n; i++ {
for x < len(bs) && (bs[x] < '0' || bs[x] > '9') && bs[x] != '-' {
x++
}
x = readInt(bs, x, &res[i])
}
return res
}

func solve(x int, lists [][]int) int {

// 只关心第一次拿到正数收益的情况
getNextValue := func(i int, pos int) *Item {
var sum int
mn := 1 << 60
for pos < len(lists[i]) {
sum += lists[i][pos]
mn = min(mn, sum)
if sum >= 0 {
it := new(Item)
it.id = i
it.pos = pos + 1
it.expect = -mn
it.gain = sum
return it
}
pos++
}
return nil
}

n := len(lists)

pq := make(PQ, 0, n)

for i := 0; i < n; i++ {
it := getNextValue(i, 0)
if it != nil {
heap.Push(&pq, it)
}
}

for pq.Len() > 0 {
it := heap.Pop(&pq).(*Item)
if it.expect > x {
// can't proceed any more
break
}
x += it.gain
it = getNextValue(it.id, it.pos)
if it != nil {
heap.Push(&pq, it)
}
}

return x
}

type Item struct {
id int
pos int
expect int
gain int
index int
}

type PQ []*Item

func (pq PQ) Len() int {
return len(pq)
}

func (pq PQ) Less(i, j int) bool {
return pq[i].expect < pq[j].expect || pq[i].expect == pq[j].expect && pq[i].gain > pq[j].gain
}

func (pq PQ) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}

func (pq *PQ) Push(item interface{}) {
cur := item.(*Item)
cur.index = len(*pq)
*pq = append(*pq, cur)
}

func (pq *PQ) Pop() interface{} {
arr := *pq
n := len(arr)
res := arr[n-1]
*pq = arr[:n-1]
res.index = -1
return res
}
32 changes: 32 additions & 0 deletions src/codeforces/set1/set19/set191/set1912/a/solution_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import "testing"

func runSample(t *testing.T, x int, lists [][]int, expect int) {
res := solve(x, lists)

if res != expect {
t.Fatalf("Sample expect %d, but got %d", expect, res)
}
}

func TestSample1(t *testing.T) {
x := 1
lists := [][]int{
{-1, 2},
{-2, 3},
{-3, 4},
}
expect := 4
runSample(t, x, lists, expect)
}

func TestSample2(t *testing.T) {
x := 1
lists := [][]int{
{-1, -1, 4},
{1, -3, -4, 8},
}
expect := 4
runSample(t, x, lists, expect)
}
49 changes: 49 additions & 0 deletions src/codeforces/set1/set19/set191/set1914/e1/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
The easy and hard versions of this problem differ only in the constraints on the number of test cases and 𝑛
. In the easy version, the number of test cases does not exceed 103
, and 𝑛
does not exceed 6
.

Recently, Alice and Bob were given marbles of 𝑛
different colors by their parents. Alice has received 𝑎1
marbles of color 1
, 𝑎2
marbles of color 2
,..., 𝑎𝑛
marbles of color 𝑛
. Bob has received 𝑏1
marbles of color 1
, 𝑏2
marbles of color 2
, ..., 𝑏𝑛
marbles of color 𝑛
. All 𝑎𝑖
and 𝑏𝑖
are between 1
and 109
.

After some discussion, Alice and Bob came up with the following game: players take turns, starting with Alice. On their turn, a player chooses a color 𝑖
such that both players have at least one marble of that color. The player then discards one marble of color 𝑖
, and their opponent discards all marbles of color 𝑖
. The game ends when there is no color 𝑖
such that both players have at least one marble of that color.

The score in the game is the difference between the number of remaining marbles that Alice has and the number of remaining marbles that Bob has at the end of the game. In other words, the score in the game is equal to (𝐴−𝐵)
, where 𝐴
is the number of marbles Alice has and 𝐵
is the number of marbles Bob has at the end of the game. Alice wants to maximize the score, while Bob wants to minimize it.

Calculate the score at the end of the game if both players play optimally.


### ideas
1. 考虑几种情况
2. i, j a[i] > a[j], b[i] > b[j]
3. 那么对于alice来说,优先选择i是更好的,他可以获得a[i]-1分,且阻止对方获得b[i]-1分
4. 如果 a[i] > a[j], 但是 b[i] < b[j]
5. 如果alice选择i, 那么得分是 a[i] - 1, 但是bob得分是b[j] - 1
6. 反过来就是 a[j] - 1, b[i] - 1
7. 所以,从alice的角度来看如果 a[i] - b[j] > a[j] - b[i], 那么就是划算的
8. a[i] + b[i] > a[j] + b[j]
9. 对bob也是一样的
Loading

0 comments on commit 3d4717b

Please sign in to comment.