第1题 CF 867E
CF 867E
题意:考虑股票市场,一共有$n$天。对于第$i$天,B君知道股票的价格是每单位$a_i$元
在每一天,可以选择买入一个单位的股票,卖出一个单位的股票,或者什么都不做。
刚开始有无穷多的钱,但是没有任何股票。
问$n$天之后最多可以赚多少钱。
解:用大根堆维护。从左往右扫,每次扫到一个数如果不大于当前堆的根,那么直接插。否则就先买(根和当前值),然后再插两个当前值到堆里。相当于这次卖是一个中转点,不一定最终在这里卖。所以在后面如果有更优解那么将会继承中转点的值,也就是返回思想。
知识点:贪心思想可以用返回、中转点思想。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cmath>
#define ms(i, j) memset(i, j, sizeof i)
#define LL long long
#define db double
#define fir first
#define sec second
#define mp make_pair
using namespace std;
namespace flyinthesky {
int n, t;
LL ans = 0;
priority_queue<int, vector<int >, greater<int > > q;
void clean() {
}
int solve() {
scanf("%d", &n);
for (int x, i = 1; i <= n; ++i) {
scanf("%d", &x);
if (!q.empty() && x > q.top()) {
ans += (LL)x - (LL)q.top();
q.pop(); q.push(x);
}
q.push(x);
}
cout << ans;
return 0;
}
}
int main() {
flyinthesky::solve();
return 0;
}
第2题 Bzoj 4198
Bzoj 4198
题意:多叉哈夫曼树。
解:按照二叉树方法贪心是错的,最后在根节点会出现节点不够用的情况。所以我们可以修改一下,将下面的节点移到上面。具体是加一堆0点以至于$(n-1) \mod (k-1)=0$(画图分析)。对于第二问,贪心最小合并次数的合并即可,
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<set>
#include<cmath>
#define ms(i, j) memset(i, j, sizeof i)
#define LL long long
#define db double
#define fir first
#define sec second
#define mp make_pair
using namespace std;
namespace flyinthesky {
struct data {
LL val, tms;
bool operator < (const data &rhs) const {
if (val == rhs.val) return tms > rhs.tms;
return val > rhs.val;
}
};
LL n, k, ans, maxd;
priority_queue<data > q;
void clean() {
maxd = ans = 0;
}
int solve() {
clean();
scanf("%lld%lld", &n, &k);
for (LL x, i = 1; i <= n; ++i) scanf("%lld", &x), q.push((data){x, 0});
while ((n - 1) % (k - 1) != 0) q.push((data){0, 0}), ++n;
for (LL i = 1; i <= (n - 1) / (k - 1); ++i) {
LL tmp1 = 0, tmp2 = 0;
for (LL j = 1; j <= k; ++j) {
data p = q.top(); q.pop();
tmp1 += p.val, tmp2 = max(tmp2, p.tms);
}
maxd = max(maxd, tmp2 + 1);
ans += tmp1;
q.push((data){tmp1, tmp2 + 1});
}
printf("%lld\n%lld\n", ans, maxd);
return 0;
}
}
int main() {
flyinthesky::solve();
return 0;
}