Codeforces Round #437B,C,D,E题目详解
来源:互联网 发布:图片纠偏软件 编辑:程序博客网 时间:2024/06/02 04:10
B题题意:给你一个答案A,让你推出用M种硬币组成N元钱的方案数为A。
思路:构造题,其实我们很容易知道用1和2就可以构造出所有的数,然后再算一算就会发现构造出的数字的方案是有规律的。读者可以自己思考思考。
#include<iostream>using namespace std;int main(){ int A; cin >> A; cout << 2 * A - 1 << " " << 2 << endl; cout << 1 << " " << 2 << endl; return 0;}
C题题意:有N组参赛者,他们要吃披萨,一片披萨有S块。现在有两种披萨,他们对这两种披萨的喜爱值不同,给出每组参赛者要吃多少块披萨,对两种披萨的喜爱值,要求我们在买披萨最少的前提下,保证总喜爱值最大。
思路 :对于ai大于bi的,我们最好给他吃第一种,ai小于bi的,最好给他第二种,如果相等则随意。这样算可能会把披萨算多了,对于ai>bi的组吃的披萨数记为suma,其他的披萨数记为sumb,如果suma%S+sumb%S>S,那么就上面这样算,原因读者可以思考一下。如果小于等于呢,这种情况对于多出来的部分只能买1个披萨了,所以此时要在上面的前提下分类讨论,最后一块到底是买a好还是b好。
代码如下:
#include<iostream>#include<vector>#include<algorithm>using namespace std;typedef long long ll;vector<pair<ll, ll>>V1, V2;int main(){ ll N, S; cin >> N >> S; ll s, a, b; ll ans = 0; ll p = 0, q = 0; for (int i = 1;i <= N;i++) { scanf("%lld%lld%lld", &s, &a, &b); if (a > b) { ans += s*a; p += s; p %= S; V1.push_back({ a - b,s }); } else { ans += s*b; q += s; q %= S; V2.push_back({ b - a,s }); } } if (p + q > S) { cout << ans << endl; return 0; } sort(V1.begin(), V1.end()); sort(V2.begin(), V2.end()); ll x = 0, y = 0; for (auto it : V1) { x += min(it.second, p)*it.first; p -= min(it.second, p); } for (auto it : V2) { y += min(it.second, q)*it.first; q -= min(it.second, q); } cout << ans - min(x, y) << endl; return 0;}
D题题意:一个人玩游戏,有n关,每一关他有2种通关时间Fi,Si,并且Fi< Si,他以Fi通过此关的概率为Pi/100,现在给你一个R,问你在保证他通过所有关时间不超过R的前提下,通关所需要的时间期望为多少?
思路:我们可以设期望为X,现在有两种操作,第一种两种方式都行,那么Xi=pi*fi+(1-pi)si,如果只能由第一种方式可行的话,那么X=pi*fi+(1-pi)(si+X)。读者可以仔细思考一下这个公式。
但现在的情况有些变化,前面的选择会影响后面的选择。所以我们可以设dp[i][j]为已经到第i关,前面i-1关花了j时间。
那么dp[i][j]=pi*(dp[i+1][j+f[i]])+(1-pi)(dp[i+1][j+s[i]])(两个操作都行时)。dp[i][j] = pi(dp[i+1][j+f[i]])+(1-pi)*(X+j+s[i])(第二种操作不行,所以要重新返回第一关)。还有两种操作都不行的dp方程,与上面类似。
那么dp[1][0]其实就等于X,其实就是来解这个一元一次方程。那么这里我们可采用二分的方式求X。
代码如下:
#include<iostream>#include<algorithm>using namespace std;int F[55], S[55];double P[55];double dp[55][5005];const double inf = 0x3f3f3f3f;int main(){ int N, R; double f, s, p; cin >> N >> R; for (int i = 1;i <=N;i++) cin >> F[i] >> S[i] >> p, P[i] = p / 100; double l = 0, r = 1e15; double mid; for (int k = 1;k < 100;k++) { mid = (l + r) / 2; for (int t = 1;t <= R;t++) dp[N + 1][t] = t; for (int t = R + 1;t < 5005;t++) dp[N + 1][t] = inf; for (int i = N;i >= 1;i--) for (int t = 0;t < 5005;t++) dp[i][t] = min(mid + (double)(t + F[i]), dp[i + 1][t + F[i]])*P[i] + min(mid + (double)(t + S[i]), dp[i + 1][t + S[i]])*(1 - P[i]); if (dp[1][0] > mid) l = mid; else r = mid; } printf("%.9f\n", mid);}
这是一个好题啊,博主想了很久才弄清楚,希望读者也要搞清楚啊。
E题题意:买卖股票,有N天股票的价格,问你怎么弄在N天后可以获得的钱数最多(可以欠账)。
思路:对于每天的股票我们其实有三种操作,买,卖,不管。那么我们只要想办法将这三种操作分开就行了,并且要保证买卖的次数相同。这里用到multiset,对于在集合里面的数,如果出现2次,就代表它被卖掉,1次则是不管,0次则代表他被买了。每次新增一个数,先往集合里面添加2次,然后再删掉最小的一个数。这里的含义就是对于这个数来说,之前如果集合中最小的比它小,不管是有两个还是一个(代表卖掉它还是不管它),都减一个(如果之前是卖掉它,那么现在明显是不管它并且卖掉当前这个比较划算,如果之前是不管它,那么现在最好就是买它并且卖掉当前这个划算)。
其中的逻辑读者可以再仔细推敲。
代码如下:
#include<iostream>#include<set>using namespace std;typedef long long ll;multiset<ll>S;int main(){ int n; cin >> n; ll ans = 0; ll temp; for (int i = 1;i <= n;i++) { scanf("%lld", &temp); S.insert(temp); S.insert(temp); S.erase(S.begin()); ans -= temp; } for (auto it : S) { ans += it; } cout << ans << endl;}
这场虽然代码简短,但是题目难度还是很大。博主从中认识到了自己和大佬的差距,补完题目之后没有了之前那么愉悦感,因为代码太简短了。。但为什么自己就做不出来。希望自己今后要更加努力才对啊。
- Codeforces Round #437B,C,D,E题目详解
- Codeforces Round #432 (Div. 2)C,D,E题目详解
- Codeforces Round #433(Div.2) C,D,E题目详解
- Codeforces Round #430(Div.2) C,D,E题目详解
- codeforces Codeforces Round #407 Div2题解 B,C,D,E
- Codeforces Round #435 (Div. 2)C,D,E,F题目详解
- Codeforces Round #186 (Div. 2)A、B、C、D、E
- Codeforces Round #258 (Div. 2)-(A,B,C,D,E)
- Codeforces Round #261 (Div. 2) A,B,C,D,E
- Codeforces Round #263 (Div. 2) A,B,C,D,E
- Codeforces Round #264 (Div. 2) A,B,C,D,E
- Codeforces Round #277 (Div. 2) A,B,C,D,E
- Codeforces Round #280 (Div. 2 A,B,C,D,E)
- Codeforces Round #287 (Div. 2) A、B、C、D、E
- Codeforces Round #287 (Div. 2)A,B,C,D,E
- Codeforces Round #288 (Div. 2) A,B,C,D,E
- Codeforces Round #293 (Div. 2) (A B C D E)
- Codeforces Round #308 (Div. 2) A B C D E
- 如何准备校招技术面试
- 文章标题
- HEVC代码学习29:getDistPart函数
- ResourceManager(二)—— AssetInfoManager
- redis的主从复制+高可用简单部署
- Codeforces Round #437B,C,D,E题目详解
- python print a+=1 报错
- 洛谷 2882[USACO] Face The Right Way 智商题(尺取法)
- 【C++】动态二维数组的创建
- C++模板:函数模板和模板函数
- 《文献管理与信息处理》 2.简易信息聚合--RSS
- HDU
- ajax同步请求执行顺序
- 各大网站CSS样式初始化、