您的位置:首页 > 其它

Codeforces 752E Santa Claus and Tangerines 二分+记忆化

2016-12-26 20:05 417 查看
点击打开链接

二分joy值 每次判定时 对于每个a[i]只要>=joy时,就拆分成a[i]/2,a[i]-a[i]/2, p[a[i]]记忆化保存每个a[i]能拆分出多少个joy即可. 时间复杂度为O(n(logn)^2) n<=1e6 ai<=1e7

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+20;
const ll inf=1e15;
ll n,k;
int a
,clo;
int p[N*10],vis[N*10];//a[i]<1e7 p[a[i]] a[i]能分成多少块x

int rd()
{
int x=0;
char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
int dfs(int m,int x)
{
if(vis[m]==clo)
return p[m];

vis[m]=clo;//第clo次记忆化 memset会TLE

if(m<x)
return p[m]=0;

//a[i] (even or odd)->(a[i]/2,a[i]-a[i]/2)
else
{
return p[m]=max(1,dfs(m/2,x)+dfs(m-m/2,x));
}
}
bool check(int x)
{
ll cnt=0;
clo++;
//判断每个人是否能分到x个
for(int i=1;i<=n;i++)
{
cnt+=dfs(a[i],x);
}
return cnt>=k;
}
int main()
{

n=rd();
k=rd();
ll s=0;
int r=0;
for(int i=1;i<=n;i++)
{
a[i]=rd();
s+=a[i];
r=max(a[i],r);
}
if(s<k)
{
puts("-1");//每人至少一个
return 0;
}
int l=1;
int ans=-1;
clo=-1e7;//
sort(a+1,a+1+n);//减小递归次数
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
{
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
cout<<ans<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: