小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力
- 二分法:
这里的思路就是假设一个小Q第一天吃糖的数量,然后使用Sum函数判断是否符合题目要求且是可以吃的最大数量,小Q第一天吃糖的数量在1~N-1之间,为了提高效率,我们使用二分法逼近那个最优值,这里注意,因为题目要求是今天吃的至少是昨天的一半,昨天吃了3个今天就怎末也得吃两个,所以在计算mid的时候要想上取整:
参考代码:
#include<cmath>
using namespace std;
int sum(int s,int N){
int sum =0;
for(int i = 0;i<N;i++){
sum+=s;
s = (s+1)>>1;
}
return sum;
}
int fun(int N,int M){
if(N==1){return M;}
int low = 1;
int high = M;
while(low<high){
int mid = (low+high+1)/2;
if(sum(mid,N)==M){
return mid;
}else if(sum(mid,N)<M){
low = mid+1;
}
else{
high = mid-1;
}
}
return low;
}
int main(){
int N = 0,M = 0;
while(cin>>N>>M){
int first = fun(N,M);
cout<<first<<endl;
}
return 0;
}
- 数学公式法(思路):
其实在看到题目的时候,我的第一反应是从爸妈回来的第一天行前看,这就是一个比为2的等比数列,但我很快发现并非如此,因为在小明头一天只吃了1颗糖后,之后也只需吃一颗糖就可以满足要求,所以并不构成等比,但很快我又尝试构造等比数列解决问题:
由题知:小Q父母N天才回来,Q有M块巧克力,所以在Q每天只吃1块的情况下,他会吃掉N个,剩下的M-N个就可以分配到他爸妈刚走的X天里,构成一个q=2的等比数列,根据等比数列求和共实可得M-N+X= 2(1+2x)/1-2,这样就可以得到这个等比数列的天数x,然后根据a1=2就可以推出ax也就是走的第一天吃了多少个,最终得到的式子是2x+1+x<=M-N+2;求得X,然后第一天吃的 就是 a1*2x-1,这种方法效率极高,但X的表达式较难实现=_=|||;