有n种长度的棍子,长度分别为2^0 ,2 ^ 1,…,2 ^ (n-1) ,每种棍子有a[i] 种,问你能组成多少个三角形。
三角形两边之和大于第三边,而2 ^ i + 2 ^ i = 2 ^ (i+1),所以两条短的边不能和一条长的边组成三角形,因此要尽量组成2条长边1条短边的情况。
一开始是从后往前处理,但是会出现问题:当前剩2个的情况下到底是让比它小的的匹配,还是让其和比它大的匹配。如1,2,2,2,2,当判断到第4个时可以选择让第四个的一个 和第五个的两个构成一个三角形,也可以构成2个却一条边的三角形。并且无法判断哪一种选择更优。
所以这种贪心策略时有问题的。
而若从前往后进行选择,首先当前最优的肯定是先把前面剩下的用2个给匹配掉,然后是自己构成3个的,然后剩下的1个或0个留给后面的解决
#include<bits/stdc++.h>
using namespace std;
#define forn(i,n) for(int i = 0;i<int(n);i++)
typedef long long LL;
LL n,cnt,a[303030],ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
cin>>n;
for(int i = 1;i<=n;i++) cin>>a[i];
for(int i = 1;i<=n;i++){
if(a[i] >= 2 * cnt) a[i] -= 2 * cnt,ans += (a[i] /3 + cnt) ,a[i] %=3 ,cnt = a[i];
else ans += a[i] / 2 ,cnt -= a[i] / 2,a[i] %= 2, cnt += a[i];
}
cout<<ans;
return 0;
}