刷题第八天(贪心加前缀和,待更新)

#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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值