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

来源:互联网 发布:网络电视是什么 编辑:程序博客网 时间:2024/04/28 00:41

点击打开链接

二分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[N],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;}elser=mid-1;}cout<<ans<<endl;return 0;} 


0 0
原创粉丝点击