文章目录
最小资金赢得最多选票
- 对每个选民进行了调查,已经知道每个人要选的人是谁,以及需要花多少钱才能让这个人选你;
- 现在要花最少的钱使你当上县长,需要你的票数比任何其他候选人都多,计算最少要花多少钱。
输入描述:
第一行输入选民数n;
后续的每行输入ai bi,ai表示第i个选民选的第ai号候选人,bi是让他选自己需要花的钱;你是0号选人(如果一个选民选你,那么ai bi均为0)
输出描述:
输出一个整数,表示花费最少的钱;
示例1
输入:
5
1 2
1 2
1 2
2 1
0 0
输出:
3
示例2
输入:
10
1 2
1 3
1 5
2 8
2 4
2 1
2 2
1 2
1 3
0 0
输出:
10
python实现:
- 线段树;
n = int(input())
max_b = 1
max_a = 0
result = 0
tree1 = [[] for i in range(10005)]
f = [[] for i in range(10005)]
num = [0 for i in range(40000)]
t = [0 for i in range(40000)]
# 分别取出a,b两个数组的最大值
for i in range(n):
params = [int(x) for x in input().split(" ")]
x = params[0]
y = params[1]
max_a = max(max_a, x)
if (y == 0):
continue
max_b = max(y, max_b)
result += y
tree1[x].append(y)
for i in range(1, max_a + 1):
temp = tree1[i]
if (len(temp) > 0):
temp.sort()
for j in range(len(temp)):
f[j + 1].append(temp[j])
def change(x, l, r, q, num, t):
if (l == r):
num[x] += 1
t[x] += 1 * l
return
mid = (l + r) >> 1
if (q <= mid):
change(x << 1, l, mid, q, num, t)
else:
change(x << 1 | 1, mid + 1, r, q, num, t)
t[x] = t[x << 1] + t[x << 1 | 1]
num[x] = num[x << 1] + num[x << 1 | 1]
def query(x, l, r, q, num, t):
if (l == r):
return 1 * l * q
mid = (l + r) >> 1
if (q == num[x << 1]):
return t[x << 1]
if (q > num[x << 1]):
return t[x << 1] + query(x << 1 | 1, mid + 1, r, q - num[x << 1], num, t)
else:
return query(x << 1, l, mid, q, num, t)
k = n
tmp = result
for i in range(1, n + 1):
k -= len(f[i])
for j in range(len(f[i])):
change(1, 1, max_b, f[i][j], num, t)
tmp -= 1 * f[i][j]
add = 0
if (k <= i):
add = query(1, 1, max_b, min(i + 1 - k, n), num, t)
result = min(result, tmp + add)
print(result)

1212

被折叠的 条评论
为什么被折叠?



