专栏文章
题解:P9863 [POI 2021/2022 R2] arm
P9863题解参与者 3已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @min6f6hk
- 此快照首次捕获于
- 2025/12/01 21:20 3 个月前
- 此快照最后确认于
- 2025/12/01 21:20 3 个月前
思路
我们发现,最优策略一定是先进行选择 ,再进行 次选择 ,然后继续进行选择 ,再进行 次选择
那么我们设当前物品数量为 ,则在进行 次选择 之后,物品数量就会变为 ,之后进行选择 ,再进行 次选择 ,物品数量就会变为
所以最后的结果一定为 ,而且 一定小于等于 。
因此,我们可以枚举 (相当于枚举进行了多少次选择 ),对所有答案取最小值。
对于每个 ,通过贪心我们可以发现当每个 约为 时,所消耗的 是最小的。
设 ,。那么,最优解一定为所有 中大于 的最小的那个数,也就是我们要求最大的那个 。而 最大不超过 ,因此我们直接枚举 即可。
最后的答案即为最小的 。
但是,注意到有可能会有浮点误差
pow(n, 1.0 / k) 或溢出问题,因此要加上一句 return LONG_LONG_MAX;。其实本应该写二分的,但是本人不会写,加个特判也能过。代码
CPP#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k,a,b,ans=LONG_LONG_MAX;
int solve(){
int num=pow(n,1.0/k);
for(int i=k;i>=0;i--){
int sum=1,cst=0;
for(int j=1;j<=i;j++){
sum*=num;
cst+=(num-1);
}
for(int j=i+1;j<=k;j++){
sum*=(num+1);
cst+=num;
}
if(sum>=n||sum<0) return b*cst+a*k;
}
return LONG_LONG_MAX;
}
signed main(){
cin>>n>>a>>b;
n++;
for(int i=1;i<=64;i++){
k=i;
int t=solve();
if(t>=0) ans=min(ans,t);
}
cout<<ans;
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...