2022-06-26 华泰证券 Fintech 比赛题解
2022-06-29
小华拼单词
小华拿到了很多个字母,他希望能拼出尽可能多的 “huatai” 单词,你能告诉他最多可以拼出多少个吗?
输入描述
输入 26 个整数 c n t cnt cnt,分别代表字母 ‘a’ 到字母 ‘z’ 的数量。
1 ≤ c n t ≤ 1 0 9 1 \leq cnt \leq 10^9 1≤cnt≤109。
输出描述
一共最多可以拼出 “huatai” 的数量。
一个 “huatai” 单词包含 1 个 h h h,1 个 u u u,2 个 a a a,1 个 t t t 和 1 个 i i i。因此我们分别求出各个字母的数量可以拼出多少个 “huatai”,并且根据木桶效应,理应选择最少的那个值。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> cnts(26, 0);
for (int i = 0; i < 26; i++)
cin >> cnts[i];
int ans = 0x7fffffff;
ans = min(ans, cnts['h' - 'a']);
ans = min(ans, cnts['u' - 'a']);
ans = min(ans, cnts['a' - 'a'] / 2); // 1 个 "huatai" 需要 2 个 'a'
ans = min(ans, cnts['t' - 'a']);
ans = min(ans, cnts['i' - 'a']);
cout << ans << endl;
return 0;
}
股票买卖的最大收益
给定股票每天变化的价格。初始股票 x x x 手,初始现金 0 元,每天可以任意次买入或卖出,但最多持有 k k k 手股票。请问最后一天结束时,将手中所有股票换算成现金后,能够得到的最大总资产是多少?
输入描述
第一行输入是哪个正整数 n n n, k k k, x x x,分别代表总天数、最大持有股票数目,以及初始股票数目。
第二行输入 n n n 个正整数 a i a_i ai,代表股票的每日价格。
题目中没有说清楚 股票必须整买整卖 容易让人造成误解,谨此说明。
根据 贪心 思想,一天中要么卖出所有股票,要么尽可能买进股票才能获得利益最大化,所以每天有 2 种状态,我们称之为 现金流 和 股票流。
再运用 动态规划 思想,当天的现金流状态可以从前一天的现金流状态直接得来,也可以从前一天的股票流状态经卖出所有股票得来,究竟是哪 取决于谁最终得到的现金最多。当天的股票流状态则更为复杂,可以用前一天的股票流状态经继续买入股票得来,或是用前一天的现金流状态经直接大幅度买入股票得来,需要特殊考虑的是:最多只能持有 k k k 手股票。因此我们应该优先选择能够获得更多股票数的状态转化而来,若两种状态能够获得的股票数一样时,应该比较哪种状态剩余的现金更多。
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
struct node {
int64_t stock; // 股票数
int64_t cash; // 现金数
node() {};
node(int64_t s, int64_t c) : stock(s), cash(c) {};
};
int main()
{
int64_t n, k, x; cin >> n >> k >> x;
vector<int64_t> price(n);
for (int64_t i = 0; i < n; i++)
cin >> price[i];
vector<vector<node>> dp(n, vector<node>(2)); // 0: 现金流, 1: 股票流
dp[0][0] = node(0, x * price[0]);
dp[0][1] = node(x, 0);
for (int i = 1; i < n; i++) {
// 现金流:只须将前一天的现金流和股票流分别转换成现金比较谁多即可
dp[i][0] = node(0, max(dp[i - 1][0].stock * price[i] + dp[i - 1][0].cash, dp[i - 1][1].stock * price[i] + dp[i - 1][1].cash));
// 股票流:假设将前一天的现金流和股票流尽可能再买入当天的股票。
int64_t stock0 = dp[i - 1][0].stock + dp[i - 1][0].cash / price[i], stock1 = dp[i - 1][1].stock + dp[i - 1][1].cash / price[i];
int64_t cash0 = dp[i - 1][0].cash % price[i], cash1 = dp[i - 1][1].cash % price[i]