主要思想:贪心+双指针
注意点:
- 每次操作都需要一定成本,具体来说,将数组从 a i a_i ai和 a i + 1 a_{i+1} ai+1 之间截断,所需成本为 ∣ a i − a i + 1 ∣ |a_i - a_{i+1}| ∣ai−ai+1∣
- 所有进行的截断操作的总成本不得超过 B B B
- 所有截断得到的子数组都必须也是平衡数组
- 只是截断a[]数组,不再对a[]数组的子数组再进行操作
思考:
- 通过一次遍历计算并存储所有潜在的截断成本到数组 k [ ] k[] k[]中。利用了平衡数组的性质:只有当遍历到的位置使得前面的子数组为平衡数组时,才记录成本
- 由于是要得出最大的截断数,所以从最小的截断成本开始,因此要对数组 k [ ] k[] k[]进行排序
- 遍历数组 k [ ] k[] k[],尝试执行每个符合题目要求的操作,同时保持最大成本不超过 B B B,每有一个成功的操作,计数器 M a x C u t MaxCut MaxCut ++;
AC代码:
#include <bits/stdc++.h>
using namespace std;
int n, B;
int a[1010];
int cost[1010];
int cnt=0;
int MaxCut=0;
int main() {
scanf("%d%d",&n,&B);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1,ji=0,ou=0;i<n;i++) //由于是子数组,所以少一
{
if(a[i]%2==0) ou++;
else ji++;
if(ji==ou) cost[cnt++]=abs(a[i]-a[i+1]);
}
sort(cost,cost+cnt);
for(int i=0;i<cnt;i++)
{
if(cost[i]<=B)
{
B-=cost[i];
MaxCut++;
}
}
printf("%d",MaxCut);
return 0;
}