E - Plants vs. Zombies
思路:直接二分答案,对每个答案进行check即可。check函数直接暴力写!(一开始想了半天以为是贪心,后来越想越麻烦,但这又不是可能是dp,所以直接暴力枚举答案即可)
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<vector> #include<map> #include<set> #include<queue> #include<stack> //#define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; double eps=0.05; ll mod=1e9+7; const int INF=0x3f3f3f3f,inf =0x3f3f3f3f; const int MAXN=2e3+10; const int maxn = 1e7+10; //ll inf=100000000000000; //template<typename T>inline void read(T &x) //{ // x=0; // static int p;p=1; // static char c;c=getchar(); // while(!isdigit(c)){if(c=='-')p=-1;c=getchar();} // while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();} // x*=p; //} typedef unsigned long long ull; const int N=2e5+7; const double PI=acos(-1.0); ll a[N]; ll m; int n; ll aa[N]; bool check(ll x){ for(int i=0;i<n;i++){ if(x%a[i]==0){ aa[i]=x/a[i]; } else { aa[i]=x/a[i]+1; } } ll ans=0; for(int i=0;i+1<n;i++){ ans++; aa[i]--; if(aa[i]<=0){continue;} ans+=2*aa[i]; aa[i+1]-=aa[i]; if(ans>m)return false; } if(aa[n-1]>0){ aa[n-1]--;ans++; ans+=aa[n-1]*2; } if(ans>m)return false; return true; } int main() { int t; scanf("%d",&t); while(t--){ scanf("%d%lld",&n,&m); for(int i=0;i<n;i++){ scanf("%lld",&a[i]); } ll l=0,r=1e12+10; ll aans=0; while(l<=r){ ll mid=(l+r)/2; //cout<<mid<<endl; if(check(mid)){ aans=mid; l=mid+1; } else { r=mid-1; } } printf("%lld\n",aans); } return 0; }