文章目录
-
- [1. 牛牛的快递](#1. 牛牛的快递)
-
- [1.1 思路](#1.1 思路)
- [1.2 源码](#1.2 源码)
- 1.3总结
- [2. 最小花费爬楼梯](#2. 最小花费爬楼梯)
-
- [2.1 思路](#2.1 思路)
- [2.2 源码](#2.2 源码)
- [3. 数组中两个字符串的最小距离](#3. 数组中两个字符串的最小距离)
-
- [3.1 思路](#3.1 思路)
- [3.2 源码](#3.2 源码)
-
- [3.2.1 第一遍](#3.2.1 第一遍)
- [3.2.2 第二遍](#3.2.2 第二遍)
- [3.3 总结](#3.3 总结)
1. 牛牛的快递
1.1 思路
一道简单的模拟题
1.2 源码
cpp
#include <iostream>
using namespace std;
#include<cmath>
int main() {
float w;
char ch;
int ret = 0;
cin >> w >> ch;
if (w <= 1)
ret += 20;
else {
ret += 20;
w -= 1;
ret += ceil(w);
}
if (ch == 'y')
ret += 5;
cout << ret << endl;
return 0;
}
1.3总结
cout << ret << endl;要加endl,刷新一下缓冲区,不加过不了。- 用了ceil向上取整函数。
2. 最小花费爬楼梯
2.1 思路
经典的动态规划
- 确定状态表示:dp[i] 表示到达i位置时的最小花费。
- 确定状态转移方程:
min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) - 填表顺序:从左向右
- 初始化:dp[0] = 0, dp[1] = 0
- 返回dp[n]
2.2 源码
cpp
#include<iostream>
#include<cstring>
/*
描述
给定一个整数数组 cost ,其中 cost[i] 是从楼梯第i 个台阶向上爬需要支付的费用,下标从0开始。
一旦你支付此费用,即可选择向上爬一个或者两个台阶。
*/
using namespace std;
const int MAXN = 100000 + 1;
int cost[MAXN];
int dp[MAXN];
//手写分析过程:
//从大到小分析 对于第 i 阶,到顶需要的花费 dp[i] = cost[i] + min(dp[i + 1] , dp[i + 2])
//最后取 min(dp[0] , dp[1])
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> cost[i];
}
if (n == 1) {
cout << cost[0] << endl;
return 0;
} else if (n == 2) {
cout << min(cost[0], cost[1]);
return 0;
} else {
memset(dp, 0, sizeof(dp));
//dp初始化 对于最后一阶和倒数第二阶而言,他们需要的花费就是他们位置的cost
dp[n - 1] = cost[n - 1];
dp[n - 2] = cost[n - 2];
//从单数第三个开始,花费 就是 cost[i] + min(dp[i + 1] , dp[i + 2])
//跳一步 和 跳两步 两种情况取花费少的情况
for (int i = n - 3; i >= 0; --i) {
dp[i] = cost[i] + min(dp[i + 1], dp[i + 2]);
}
//最后从"从0开始"和"从1开始" 两者选小的那个
//实际上,二者表达的是 从0 、1开始之后的能实现的最低花费已经计算出来了
//选择只是为了选择 "从哪个开始更优"
cout << min(dp[0], dp[1]) << endl;
}
return 0;
}
3. 数组中两个字符串的最小距离
3.1 思路
- 暴力解法(双指针遍历数组)
- 优化暴力解法(一个指针,两个变量,一次循环遍历解决问题)
- 预处理的思想,不再用指针遍历,而是用变量存储。
3.2 源码
3.2.1 第一遍
cpp
#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include <cstdlib>
int main()
{
int n = 0;
cin >> n;
vector<string> strs;
for (int i = 0; i < n; i++)
{
string str;
cin >> str;
strs[i] = str;
}
string str1, str2;
cin >> str1 >> str2;
int prev1, prev2;
prev1 = prev2 = -1;
int ret = 0;
for (int i = 0; i < n; i++)
{
if (strs[i] == str1)
{
prev1 = i;
if(strs[prev2] == str2)
ret = prev1 - prev2;
}
else if (strs[i] == str2)
{
prev2 = i;
if(strs[prev1] == str1)
ret = prev1 - prev2;
}
}
cout << abs(ret) << endl;
return 0;
}
3.2.2 第二遍
cpp
#include<iostream>
#include<string>
using namespace std;
int main() {
int n;
string s;
string s1, s2;
cin >> n;
cin >> s1 >> s2;
int prev1 = -1, prev2 = -1, ret = 0x3f3f3f3f;
for (int i = 0; i < n; i++) {
cin >> s;
if (s == s1) {
if (prev2 != -1)
ret = min(ret, i - prev2);
prev1 = i;
}
if (s == s2) {
if (prev1 != -1)
ret = min(ret, i - prev1);
prev2 = i;
}
}
if (ret == 0x3f3f3f3f) cout << -1 << endl;
else cout << ret << endl;
return 0;
}
3.3 总结
- 没有必要真的定义一个字符数组,字符数组的是很珍贵的,数组的意义让你能重复遍历,但是,咱们完全可以一次遍历结束。
- 注意"数组"不要越界。
完