题意:给你一个n,紧接着n个正数,然后有一种操作:选择一个x满足(x*2+1<=n)一次可以把下标为 x,2*x,2*x+1的三个数同时减一;
问,最少几次操作可以使n个数字变为零(已经是0的就不会再减1了)
这里一个坑点就是 即使下标为x的数已经是零了,你还是可以选择 x,并且 让x, 2*x , 2*x+1中不为零的减一;
这个题说要最少的次数使所有数字减为零,因为选择前面的x可以同时让后面的2*x,2*x+1都减少,所以从后面开始,先让后面的减为零,依次往前推减少的数量;
这样也是用的操作最少的,简而言之就是让一次操作,作用尽量多的下标;
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <vector> 6 #include <set> 7 #include <algorithm> 8 using namespace std; 9 typedef long long ll; 10 const int maxn=1e5+5; 11 int a[maxn]; 12 int main() 13 { 14 int n; 15 cin>>n; 16 for(int i=1;i<=n;i++) 17 { 18 cin>>a[i]; 19 } 20 int m=(n-1)/2; 21 if(m<=0||(m*2+1<n)) 22 { 23 printf("-1\n"); 24 return 0; 25 } 26 ll sum=0; 27 for(int i=n;i>1;i-=2) 28 { 29 if(a[i]!=0||a[i-1]!=0) 30 { 31 sum+=max(a[i],a[i-1]); 32 if(a[i>>1]>=max(a[i],a[i-1])) 33 a[i>>1]-=max(a[i],a[i-1]); 34 else a[i>>1]=0; 35 } 36 } 37 sum+=a[1]; 38 cout<<sum<<endl; 39 40 return 0; 41 }