二分
哎,二分,二分,二分,我咋就没想到啊,在一篇博客上看到一句话:
一般此类最小值最大问题都是二分,此题显然也是可以二分植物的高度的。
博客链接:https://www.cnblogs.com/mountaink/p/9921988.html
就是直接二分答案,然后判断行了,如果满足题意,l=mid+1,继续判断,如果不满足题意,r=mid-1。
其他的就是注意一下当i等n的时候,还有就是注意用long long,其他的真的没什么了,哎,2018年ICPC青岛站的铜牌题,真的是太简单了,做的时候没想到是二分,想到了这个题真的超级简单啊,还是太菜了......
ACcode
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<sstream>
#include<cstdlib>
#include<time.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define repp(i,n,a) for(int i=n;i>=a;i--)
#define mem(a,x) memset((a),(x),sizeof ((a)))//x只能是0或-1或false或true
#define debug(x) cout<<"X: "<<(x)<<endl
#define de cout<<"************"<<endl
#define lowbit(x) ((x)&(-x))
#define lson rt<<1
#define rson rt<<1|1
#define gcd(a,b) __gcd(a,b)
#define lcm(a,b) a*b/(__gcd(a,b))
#define inf 0x3f3f3f3f//1e9+6e7
#define Eps 1e-8
#define Mod 1000000000
typedef long long ll;
typedef unsigned long long ull;
const double pi=acos(-1.0);
using namespace std;
const int N=100010;
ll a[100010];
ll b[100010];
ll n,m;
bool ok(ll x)
{
ll p=m;
for(int i=1;i<=n;i++)
b[i]=0;
for(int i=1;i<=n;i++)
{
if(i==n&&a[i]*b[i]>=x)
return true;
p--;
b[i]++;
if(p<0)
return false;
if(a[i]*b[i]>=x)
continue;
if((x-a[i]*b[i])%a[i]==0)
{
p-=((x-a[i]*b[i])/a[i])*2;
b[i+1]+=((x-a[i]*b[i])/a[i]);
b[i]+=((x-a[i]*b[i])/a[i]);
}
else
{
p-=((x-a[i]*b[i])/a[i]+1)*2;
b[i+1]+=((x-a[i]*b[i])/a[i]+1);
b[i]+=((x-a[i]*b[i])/a[i]+1);
}
if(p<0)
return false;
}
return true;
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
ll minn=100010;
for(int i=1;i<=n;i++)
{scanf("%lld",&a[i]);minn=min(minn,a[i]);}
ll l=0,r=m*minn;
ll ans=0;
while(l<=r)
{
ll mid=(l+r)/2;
if(ok(mid))
{l=mid+1;ans=max(ans,mid);}
else
r=mid-1;
}
if(ok(l-1))
ans=max(ans,l-1);
if(ok(r-1))
ans=max(ans,r-1);
if(ok(l))
ans=max(ans,l);
if(ok(r))
ans=max(ans,r);
if(ok(l+1))
ans=max(ans,l+1);
if(ok(r+1))
ans=max(ans,r+1);
if(ok(l+2))
ans=max(ans,l+2);
if(ok(r+2))
ans=max(ans,r+2);
printf("%lld\n",ans);
}
return 0;
}