E. Pavel and Triangles dp+问题转化

E. Pavel and Triangles dp+问题转化

题意

给出n种线段,每种线段给出一定数量,其中每个线段都是
\(2^k\) 问最多能组成多少个三角形

思路

因为每个是\(2^k\)所以能组成三角形的线段要么是ABB要么是AAA 问题就转化成了凑ABB和BBB的组成怎么凑最多
怎么凑最多呢,可以注意到 ABB 和BBB 都有一对BB 所以我们优先凑对子 然后取和凑不到BBB的去组成三角形
这可能有点不好解释,从代码来说就是从后往前扫,先凑对子,如果当前的\(a[i]\mod(2)==1\)也就是凑完对子还有剩余,这个剩余不可能和后面的组成成三角形了,所以直接拿出一个对子来跟它凑成一个三角形,最后看有几个对子 最高的对子和最低的对子拿出一个可以凑成一个三角形,其实也就相等与每拿出3个线段都可以凑成一个三角形,所以只要duizi*2/3就知道其能凑成多少个三角形了

#include<bits/stdc++.h>
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;i++)
#define MS(arr,arr_value) memset(arr,arr_value,sizeof(arr)) 
#define F first 
#define S second
#define pii pair<int ,int >
#define mkp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn = 3e5+4;
int a[maxn];
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i];
    ll ans=0,duizi=0;
    for(int i=n-1;i>=0;i--){
        duizi+=a[i]/2;
        if(duizi&&a[i]%2){
            duizi--;
            ans++;
        }
    }
    ans+=duizi*2/3;
    cout<<ans<<endl;

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ttttttttrx/p/10800710.html