import os
import sys
# 请在此输入您的代码
n, B=map(int,input().split())
a=list(map(int,input().split()))
sum=0 #用于判断奇数与偶数的个数
cnt=[]#存放可切片的位置
for i in range(n):
if a[i]&1:
sum=sum+1
else :
sum=sum-1
if sum==0 and i+1<n: #当奇偶数相同且满足零花钱个数的要求时
#可切片 并将可切片的位置de花费代价进行存放
cnt.append(abs(a[i+1]-a[i]))
cut=0 #进行操作的次数
cnt.sort()
for c in cnt:
if B>=c:
B-=c
cut+=1
else:
break
print(cut)
小蓝的零花钱
解题思路
首先,我们可以将题目中的序列看成偶数和奇数的交错序列。我们可以用变量 sumsum 记录当前序列中偶数和奇数的个数之差,当 sumsum 等于 00 时,说明当前位置可以进行一次操作,因为此时序列可以被分成两段,且每个段中奇数和偶数的个数相等。
对于每次操作,我们需要计算其代价。我们可以将两个相邻操作之间的元素放在一起,这样得到的新序列中奇数和偶数的个数之差依然为 00。那么我们可以计算相邻两次操作之间的元素差的绝对值,从中选取代价最小的一次操作执行。
接下来,我们可以将每个可操作的位置看成一个区间。假设共有 mm 个可操作的位置,对这 mm 个区间按照代价从小到大排序,然后从小到大枚举每个区间,如果当前的预算 BB 足够进行这个区间的操作,那么就执行这个操作,并将答案 ansans 加 11,同时减去操作的代价 cnt_icnti。如果 BB 不足以进行这个区间的操作,那么就结束枚举,输出答案 ansans。
时间复杂度为 O(n\log n)O(nlogn),其中 \log nlogn 为排序的时间复杂度。
AC_Code
- C++
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n , a[N] , cnt[N];
signed main()
{
int n , B;
cin >> n >> B;
for(int i = 1 ; i <= n ; i ++) cin >> a[i];
int sum = 0 , now = 0;
for(int i = 1 ; i <= n ; i ++){
if(a[i] & 1) sum ++ ;
else sum -- ;
if(sum == 0 && i + 1 <= n)
cnt[++ now] = abs(a[i + 1] - a[i]);
}
sort(cnt + 1 , cnt + 1 + now);
int ans = 0;
for(int i = 1 ; i <= now ; i ++){
if(B >= cnt[i]) B -= cnt[i] , ans ++ ;
else break ;
}
cout << ans << '\n';
return 0;
}
- Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int B = scan.nextInt();
int[] a = new int[n + 1];
for (int i = 1; i <= n; i++) a[i] = scan.nextInt();
int sum = 0, now = 0;
int[] cnt = new int[n + 1];
for (int i = 1; i <= n; i++) {
if (a[i] % 2 == 1) sum++;
else sum--;
if (sum == 0 && i + 1 <= n) cnt[++now] = Math.abs(a[i + 1] - a[i]);
}
Arrays.sort(cnt, 1, now + 1);
int ans = 0;
for (int i = 1; i <= now; i++) {
if (B >= cnt[i]) {
B -= cnt[i];
ans++;
} else break;
}
System.out.println(ans);
}
}
- Python
n, B = map(int, input().split())
a = list(map(int, input().split()))
sum = 0
cnt = [] # 记录每个区间的代价
for i in range(n):
if a[i] & 1:
sum += 1
else:
sum -= 1
if sum == 0 and i + 1 < n:
cnt.append(abs(a[i + 1] - a[i]))
cnt.sort()
ans = 0
for c in cnt:
if B >= c:
B -= c
ans += 1
else:
break
print(ans)