2022-02-21每日刷题打卡

2022-02-21每日刷题打卡

一本通——动态规划

1281:最长上升子序列

【题目描述】

一个数的序列bibi,当b1<b2<…<bSb1<b2<…<bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1,a2,…,aN)(a1,a2,…,aN),我们可以得到一些上升的子序列(ai1,ai2,…,aiK)(ai1,ai2,…,aiK),这里1≤i1<i2<…<iK≤N1≤i1<i2<…<iK≤N。比如,对于序列(1,7,3,5,9,4,8),有它的一些上升子序列,如(1,7),(3,4,8)等等。这些子序列中最长的长度是4,比如子序列(1,3,5,8)。

你的任务,就是对于给定的序列,求出最长上升子序列的长度。

【输入】

输入的第一行是序列的长度N(1≤N≤1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。

【输出】

最长上升子序列的长度。

【输入样例】

7 1 7 3 5 9 4 8
【输出样例】
4

准备一个动态规划数组dp,dp[i]的意思是,以第i个数为末尾的最长递增序列为dp[i]。遍历数组,每次遍历一个位置便从那个位置回头遍历一遍,如果回头遍历的数小于当前的数,就把那个数的dp+1赋给当前数的dp(此过程中要取最大值)。

最后遍历一遍dp数组,取最大值输出。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>


int main()
{
	int n;
	cin >> n;
	vector<int>v(n);
	for (int i = 0; i < n; i++)cin >> v[i];
	vector<int>dp(n,1);
	int res = 1;
	for (int i = 1; i < n; i++)
	{
		for (int j = i-1; j >= 0; j--)
		{
			if (v[i] > v[j])
			{
				dp[i] = max(dp[i], dp[j] + 1);
				res = max(res, dp[i]);
			}
		}
	}
	cout << res << endl;
	return 0;
}
【例9.11】01背包问题

【题目描述】

一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,…,WnW1,W2,…,Wn,它们的价值分别为C1,C2,…,CnC1,C2,…,Cn,求旅行者能获得最大总价值。

【输入】

第一行:两个整数,MM(背包容量,M<=200M<=200)和NN(物品数量,N<=30N<=30);

第2…N+12…N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。

【输出】

仅一行,一个数,表示最大总价值。

【输入样例】

10 4 2 1 3 3 4 5 7 9
【输出样例】
12
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

typedef long long ll;
const int N = 210;
ll f[N], v[N], w[N];

int main()
{
	int n,m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> v[i] >> w[i];
	for (int i = 0; i < m; i++)
	{
		for (int j = n; j >= v[i]; j--)
		{
			f[j] = max(f[j], f[j - v[i]] + w[i]);
		}
	}
	cout << f[n] << endl;
	
	return 0;
}
1259:【例9.3】求最长不下降序列

【题目描述】

设有由n(1≤n≤200)n(1≤n≤200)个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)b(1)、b(2)、……、b(n)若存在i1<i2<i3<…<iei1<i2<i3<…<ie 且有b(i1)<=b(i2)<=…<=b(ie)b(i1)<=b(i2)<=…<=b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的不下降序列。

例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。例中13,16,18,19,21,22,63就是一个长度为77的不下降序列,同时也有7 ,9,16,18,19,21,22,63组成的长度为88的不下降序列。

【输入】

第一行为nn,第二行为用空格隔开的nn个整数。

【输出】

第一行为输出最大个数maxmax(形式见样例);

第二行为maxmax个整数形成的不下降序列,答案可能不唯一,输出一种就可以了,本题进行特殊评测。

【输入样例】

14 
13 7 9 16 38 24 37 18 44 19 21 22 63 15
【输出样例】
max=8 
7 9 16 18 19 21 22 63

注意这个题,说的是不递减,不是递增,意思是等于和大于都可以,就是这里我被卡了一天,但题目明明说了数都各不相等,哪还有等于的说法嘛,出题不仔细啊,知道是这个地方出问题的时候我都要疯了(哭

就是普通的求个最长不递减序列的长度问题(做法同求最长递增序列),但是多了个输出序列的部分,对于这点有两个方法。

一:就先正常的求最长不递减序列的长度,然后记下最长序列的末尾数下标ans。然后根据这个下标为起点回头找,要找的是数小于当前元素,且长度比最长长度小1的元素,找到后更新一下记录的最长长度和元素,继续找下一个长度比记录长度小1且数小于我们记录的数的……以此类推,当找到最长长度为1时结束,把找到的序列输出。例:比如按照样例来说,最长长度是8,序列的末尾元素是63,下标是12,我们以12为起点去找长度为7的序列的末位数,且要小于63,即22,再去找长度为6……。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

const int N = 210;
int f[N],h[N];

void printf01(int num)
{
	cout << num << " ";
}

int main()
{
	int n;
	cin >> n;
	unordered_map<int, vector<int>>mymap;
	for (int i = 0; i < n; i++)
	{
		cin >> h[i];
	}
	f[0] = 1;
	int res = 1,ans=0;
	for (int i = 1; i < n; i++)
	{
		f[i] = 1;
		for (int j = i - 1; j >= 0; j--)
		{
			
			if (h[i] >= h[j])
			{
				f[i] = max(f[i], f[j] + 1);
				if (f[i] > res)
				{
					res = f[i];
					ans = i;
				}
			}
		}
	}
	
	cout << "max=" << res << endl;
	vector<int>v;
	int num = h[ans];
	v.push_back(num);
	for (int i = ans - 1; i >= 0; i--)
	{
		if (f[i] == res - 1 && h[i] <= num)
		{
			res--;
			num = h[i];
			v.push_back(num);
		}
	}
	reverse(v.begin(), v.end());
	for_each(v.begin(), v.end(), printf01);
	return 0;
}

第二个方法是用一个数组p,记录序列的上一个元素的下标,比如我们求样例的最长长度时,遍历到第3个元素9时,我们知道它可以接到第二个元素7上,所以数组里p[2]=1;如果当前遍历到的元素不能接到任何数上,那数组p就记录自身的下标,比如p[0]=0。这样依次类推,我们求完最长长度后,记录序列最后一个元素的下标,根据这个下标在p数组中取出序列的上一个下标……以此类推,当取出的下标为自身时,说明这是序列的最后一个数,结束程序。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

typedef long long ll;
const int N = 210;
ll f[N], h[N], p[N];

void printf01(ll num)
{
	cout << num << " ";
}

int main()
{
	int n;
	cin >> n;
	unordered_map<ll, vector<ll>>mymap;
	for (int i = 0; i < n; i++)
	{
		cin >> h[i];
		p[i] = i;
	}
	f[0] = 1;
	ll res = 1, ans = 0;
	//13 7 9 16 38 24 37 18 44 19 21 22 63 15
	for (int i = 1; i < n; i++)
	{
		f[i] = 1;
		for (int j = i - 1; j >= 0; j--)
		{

			if (h[i] >= h[j])
			{
				if (f[j] + 1 > f[i])
				{
					f[i] = f[j]+1;
					p[i] = j;
				}
				if (f[i] > res)
				{
					res = f[i];
					ans = i;
				}
			}
		}
	}

	cout << "max=" << res << endl;
	vector<ll>v;
	bool flag = true;
	while (ans >= 0 && (p[ans] != ans) || (p[ans] == ans && flag))
	{
		if (p[ans] == ans)flag = false;
		v.push_back(h[ans]);
		ans = p[ans];
	}
	reverse(v.begin(), v.end());
	for_each(v.begin(), v.end(), printf01);
	return 0;
}

蓝桥杯——历届真题

历届真题 特别数的和【第十届】【省赛】【B组】

问题描述

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到
  40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。请问,在 1 到 n 中,所有这样的数的和是多少?

输入格式

输入一行包含两个整数 n。

输出格式

输出一行,包含一个整数,表示满足条件的数的和。

样例输入

40

样例输出

574

评测用例规模与约定

对于 20% 的评测用例,1 ≤ n ≤ 10。 对于 50% 的评测用例,1 ≤ n ≤ 100。对于 80% 的评测用例,1 ≤ n ≤ 1000。对于所有评测用例,1 ≤ n ≤ 10000。

#include<iostream>
using namespace std;




int main()
{
	int n,res=0;
	cin >> n;
	for (int j = 1; j <= n; j++)
	{
		int num = j;
		while (num)
		{
			int ans = num % 10;
			num /= 10;
			if (ans == 0 || ans == 1 || ans == 2 || ans == 9)
			{
				res += j;
				break;
			}
		}
	}
	cout << res << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 Apache POI 库来读取本地的 xlsx 文件,并实现计算每个工号每天的最晚打时间减去最早打时间的功能。下面是一个示例代码: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.IOException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; public class ReadXlsxFile { public static void main(String[] args) { String filePath = "path/to/xlsx/file.xlsx"; // 替换为你的xlsx文件路径 try (FileInputStream fis = new FileInputStream(filePath); Workbook workbook = new XSSFWorkbook(fis)) { Sheet sheet = workbook.getSheetAt(0); // 假设数据在第一个工作表中 Map<String, LocalDateTime[]> employeeTimes = new HashMap<>(); for (Row row : sheet) { Cell employeeIdCell = row.getCell(0); Cell timestampCell = row.getCell(1); String employeeId = employeeIdCell.getStringCellValue(); LocalDateTime timestamp = LocalDateTime.parse(timestampCell.getStringCellValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); LocalDate date = timestamp.toLocalDate(); LocalTime time = timestamp.toLocalTime(); LocalDateTime dateTime = LocalDateTime.of(date, time); if (employeeTimes.containsKey(employeeId)) { LocalDateTime[] times = employeeTimes.get(employeeId); times[0] = times[0].isBefore(dateTime) ? times[0] : dateTime; // 更新最晚打时间 times[1] = times[1].isAfter(dateTime) ? times[1] : dateTime; // 更新最早打时间 } else { employeeTimes.put(employeeId, new LocalDateTime[]{dateTime, dateTime}); } } for (Map.Entry<String, LocalDateTime[]> entry : employeeTimes.entrySet()) { String employeeId = entry.getKey(); LocalDateTime[] times = entry.getValue(); LocalDateTime earliestTime = times[1]; LocalDateTime latestTime = times[0]; System.out.println("Employee ID: " + employeeId); System.out.println("Earliest Time: " + earliestTime); System.out.println("Latest Time: " + latestTime); System.out.println("Time Difference: " + earliestTime.until(latestTime)); System.out.println(); } } catch (IOException e) { e.printStackTrace(); } } } ``` 请将代码中的 `path/to/xlsx/file.xlsx` 替换为你的 xlsx 文件的实际路径。此代码会使用 Apache POI 库读取 xlsx 文件的每一行,将工号和对应的打时间提取出来,并计算每个工号每天的最晚打时间减去最早打时间,并输出到控制台。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值