社区讨论
90分求助
P4040[AHOI2014/JSOI2014] 宅男计划参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lp13k6al
- 此快照首次捕获于
- 2023/11/16 19:17 2 年前
- 此快照最后确认于
- 2023/11/16 20:50 2 年前
为了防止超出long long范围,我把判断改成了```cpp
v[i].second+1>1e18/x
CPP
但还是没过
```cpp
#include<iostream>
#include<vector>
#include<algorithm>
#define ll uint64_t
using namespace std;
ll m,f;
int n;
vector< pair<ll,ll> > v;
bool cmp(pair<ll,ll> s1,pair<ll,ll> s2){
if(s1.first==s2.first) return s1.second>s2.second;
return s1<s2;
}
void input(){ //读入数据
cin>>m>>f>>n;
for(int i=0;i<n;i++) {
pair<ll,ll> tem;
cin>>tem.first>>tem.second;
v.push_back(tem);
}
}
void sort_v(){ //将食物按价格排序,删去价格高但保质期低的食物,修改 n=v.size()
sort(v.begin(),v.end(),cmp);
auto pre = v.begin();
for(auto it = v.begin()+1;it!=v.end();it++){
if((*it).second<=(*pre).second) {
v.erase(it);
it = pre;
}
pre = it;
}
n = v.size();
}
ll get_ans(ll x){ //表示买x次外卖能活几天
if(x==0) return 0;
ll w = m-x*f;
ll ans = 0;
for(int i=0;i<n;i++){ //表示买到了第几种食物
ll num = w/v[i].first; //这种食物最多能买多少个
if(num==0) break; //一个都买不了,不买了
ll max_num; //表示这种食物最多能买几个不过期的
if(i==0){
if(v[i].second+1>1e18/x) {
max_num = num+1;
}
else max_num = (v[i].second+1)*x;
}
else{
if(v[i].second-v[i-1].second>1e18/x) {
max_num = num+1;
}
else max_num = (v[i].second-v[i-1].second)*x;
}
if(num>max_num) num = max_num;//如果买的食物超过了保质期,就只买保质期内的食物
ans += num;
w -= num*v[i].first;
}
return ans;
}
int main(){
input();
sort_v();
//此题是单峰函数,使用三分来求解最大值
ll r = m/(f+v[0].first);
ll l = 0;
ll mid,midl,midr;
while(r-l>1){ //以外卖次数进行三分
mid = (l+r)/2;
midl = mid-1;
midr = mid+1;
if(get_ans(midl)>get_ans(midr)) r = mid;
else l = mid;
}
cout<<max(get_ans(l),get_ans(r));
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...