Kvalitetni
首先一个重要结论是,由于这个式子中所有参数的取值范围都是任意实数,所以任意一个式子的取值都应该是连续的,也就是说假如一个式子的最大取值为
但最大值如何求呢?如果是和的形式那很简单,直接把这个式子中所有部分的最大值加起来,然后和 limit 取较小值即可,因为根据上面的结论,假如和大于了 limit,那么我们可以通过调整式子的参数使得它的值变得小一些然后使得整个大式子的值刚好等于 limit。
那乘的形式怎么办呢?小学奥数说过和定差小积大,也就是
个人用的递归写法,人傻常熟大,仅供参考。
#include<bits/stdc++.h>
//#define feyn
const int N=1000010;
const int M=100;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline double min(double s1,double s2){
return s1<s2?s1:s2;
}
stack<int>st;
int m,len,a[M],pl[N];
char w[N];
inline double f(int l,int r){
if(l==r)return a[1];//如果括号中只有一个数直接反悔limit
int n=0;double data[M];//记录这个区间内所有柿子的最大值
char op;
for(int i=l;i<=r;i++){
if(w[i]=='(')data[++n]=f(i+1,pl[i]-1),i=pl[i];
else op=w[i];//记录这些柿子用什么符号连接
}
if(n==1)return data[1];
if(op=='+'){
double sum=0;
for(int i=1;i<=n;i++)sum+=data[i];
return min(a[n],sum);//如上文,返回和和limit的较小值
}
if(op=='*'){
double ava,ans=1,sum=a[n];
sort(data+1,data+n+1);//从小到大贪心选择
int pl=1;
while(pl<=n){
ava=sum/(n-pl+1);
if(ava<=data[pl]){
for(;pl<=n;pl++)ans*=ava;
break;
}
for(;pl<=n;pl++){
if(data[pl]<=ava)ans*=data[pl],sum-=data[pl];
else break;
}
}
return ans;//返回即可
}
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);
for(int i=1;i<=m;i++)read(a[i]);
scanf("%s",w+1);len=strlen(w+1);
for(int i=1;i<=len;i++){
if(w[i]=='(')st.push(i);
if(w[i]==')')pl[st.top()]=i,st.pop();
//预处理出每个左括号对应右括号的位置
}
printf("%f\n",f(1,len));
return 0;
}
一如既往,万事胜意
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具