1. 程式人生 > 實用技巧 >2018ICPC青島區域賽

2018ICPC青島區域賽

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; }