题目描述
小爱有 m 元钱,有 n 个项目等待她的投资,每个项目只能投资一次。其中第 i 个项目要求先支出成本 c_i 元,待项目完成后,可以收回全部成本,且获得 p_i 元利润,若小爱的钱不足 c_i ,就没法投资这个项目了。
投资不必按照项目的编号顺序进行,可以用老项目收回的成本及利润支付新项目的成本。若小爱只能投资 k 个项目,那么她最多可以积累多少钱呢?
输入 n,k,m 3 2 1; 接下来每行是c_i 和p_i
1 1
2 2
3 3 输出 :4 说明:先做第一个项目再做第二个项目,第三个项目虽然赚钱最多,但小爱没时间积累足够的本金
最多积累多少钱,所以肯定是每次本金允许下投资利润最大的,这样得到的更多,下一次可投资的项目更多。
使用结构体来记录 输入的数据,然后在排序时,根据成本,从小到大排序 sort(, , cmp);
使用优先队列来记录增加的利润premium
我看了题解,是贪心的思想。不过我觉得本质上,这道题是用模拟的方式解决。
所以我们只需要:
①对所有项目按照本金要求c_i从小到大排序,这样更新可投资项目更方便
②用一个优先队列存储所有可投资项目的利润,在成本小于本金的情况下(while project[i].cost<=m )每次取出最大的一个进行投资。投资完把新的可投资项目的利润放进这个优先队列。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100005
#define rep(i,l,r)for (int i=(l);i<=(r);i++)
struct Project {
ll cost;
ll price;
}project[maxn];
ll n,k,m;
int pos=1;
int cnt=0;
bool cmp(Project a, Project b){
return a.cost<b.cost;
}
int main(){
cin>>n>>k>>m;
for (int i=1;i<=n;i++){
cin>>project[i].cost>>project[i].price;
}
sort(project+1,project+1+n,cmp);
priority_queue<ll> q;
while (cnt<k){
while(pos<=n && project[pos].cost<=m){
q.push(project[pos].price);
pos++;
}
if (q.empty()) break;
ll premium=q.top();
q.pop();
m=m+premium;
cnt++;
}
cout<<m;
return 0;
}