#508. 两人过河
题目描述
有 n 个人希望在晚上通过一座桥。在任何时刻,最多只能有两个人在桥上,并且必须要带着手电筒才能过桥。现在只有一个手电筒,所以必须安排某种顺序,使得手电筒可以被带回去让更多的人过桥。每个人都有不同的过桥时间,两个人一起过桥所用的时间等于其中较慢的一个人的过桥时间。现求所有人过桥的最短时间。
输入
第一行一个整数 n。(1≤n≤1000)
接下来 n 行,每行一个整数表示第 i 人的过桥时间 Ti。(1≤Ti≤100)
输出
输出所有人过桥的最短时间。
样例输入
4
1
5
2
10
样例输出
17
样例说明
让 1,2 先过桥,然后让 1 回来,让 5,10 过桥,然后 2 回来再和 1 一起过桥,时间为 2+1+10+2+2=17。
数据规模与约定
时间限制:1 s
内存限制:256 M
100% 的数据保证 1≤n≤1000
//当人数大于三个人的时候讨论特殊性:
当人数为4的时候:1 2 5 10
最佳过桥策略是:(1)让最快的来送灯:1过来;
(2)让最慢的和次慢的一起过桥
(3)让次快的来送灯
(4)最快的和次快的一起开心过桥
但是还有另一种情况不能用这个策略:1 100 100 100
若还是采用上面的策略,则时间是401;
所以此时的过桥策略:
(1)让最快的来送灯
(2)让次慢的和最快的一起过桥
(3)让最快的来接最慢的
(4) 让最快的和最慢的一起骂骂咧咧过桥
此时的时间是 1+100+`100+100=301
所以我们的策略应该采取上面两种方法的最优解
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
int main() {
int n;
cin >> n;
vector<int> vec(n);
for (int i = 0; i < n; i++) {
cin >> vec[i];
}
sort(vec.begin(), vec.end());
int sum = 0;
for(int i=n-1;i>=0;i-=2){
if (i == 0) {
sum += vec[0];
break;
}
else if (i == 1) {
sum += vec[1];
break;
}
else if (i == 2) {
sum += vec[0] + vec[1]+vec[2];
break;
}
else {
sum += min(vec[0] + vec[i] + vec[1] + vec[1],vec[0]+vec[i-1]+vec[0]+vec[i]);
}
}
cout << sum << endl;
}
717. 1比特与2比特字符
有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。
现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。
示例 1:
输入:
bits = [1, 0, 0]
输出: True
解释:
唯一的编码方式是一个两比特字符和一个一比特字符。所以最后一个字符是一比特字符。
示例 2:
输入:
bits = [1, 1, 1, 0]
输出: False
解释:
唯一的编码方式是两比特字符和两比特字符。所以最后一个字符不是一比特字符。
class Solution {
public:
bool isOneBitCharacter(vector<int>& bits) {
int i=0;
while(i<bits.size()-1){
if(bits[i]==0){
i++;
}
else{
i+=2;
}
}
return i==bits.size()-1;
}
};
#510. 飞行员配对
查理获得了一家运输公司的定期航线。为了赢利,他必须尽可能地降低成本。他的公司有 N(N 是偶数)个飞行员组成的 N/2 个机组。每个机组包括两个飞行员——机长和他的助手。机长必须比他的助手年长。每个飞行员有两个可能的工资合同——>作为机长和作为助手。同一个飞行员当机长的工资高于当助手的工资,然而就同一个机组而言,一个助手的工资可能高于他的机长。现求将飞行员按最佳组合编组后,所需支付给飞行员的最少工资总额;
输入
第一行一个偶数 N。(2≤N≤10000)
接下来的 N 行,包含每个飞行员的工资,按飞行员的年龄排序,最年轻的飞行员的工资排在第一个。每行包含两个整数,分别为第 i 名飞行员做机长的工资 xi 和做助手的工资 yi。(1≤yi≤xi≤100000)
输出
输出配对后支付的最少工资总额。
样例输入
6
5000 3000
4000 1000
9000 7000
11000 5000
7000 3000
8000 6000
样例输出
33000
数据规模与约定
时间限制:1 s
//每次新增两个人,肯定年龄最长的做机长,年龄小的做机长或者副手
故有两个策略:(1)i做机长,i-1做副手
(2)i做机长,i-1也做机长
我们采取优先队列,将当前人做机长和做副手的差值放在队列中
#include<iostream>
using namespace std;
#include<queue>
int x[10005], y[10005];
int main() {
priority_queue<pair<int, int> > que;
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x[i] >> y[i];
}
int ans = x[2] + y[1];//初始化,年龄最长的做机长,年龄小的做副驾,此时能调动的是x[2]可能不会做机长了
que.push({
x[2] - y[2], 2 });
for (int i = 4; i <= n; i += 2) {
int ans1 = x[i] + y[i - 1] + ans;//情况1:新来的两个一个年龄最长的做机长一个做助手
int ans2 = x[i] + x[i