USACO 2024 December Contest, Gold

Problem 3. Job Completion

Bessie the cow has NN (1≤N≤2⋅1051≤N≤2⋅105) jobs for you to potentially complete. The ii-th one, if you choose to complete it, must be started at or before time sisi and takes titi time to complete (0≤si≤1018,1≤ti≤10180≤si≤1018,1≤ti≤1018).

What is the maximum number of jobs you can complete? Time starts at 00, and once you start a job you must work on it until it is complete, without starting any other jobs in the meantime.

INPUT FORMAT (input arrives from the terminal / stdin):

The first line contains TT, the number of independent test cases (1≤T≤101≤T≤10). Each test case is formatted as follows.

The first line contains NN.

Each of the next NN lines contains two integers sisi and titi. Row i+1i+1 has the details for the iith job.

It is guaranteed that the sum of NN over all test cases does not exceed 3⋅1053⋅105.

OUTPUT FORMAT (print output to the terminal / stdout):

For each test case, the maximum number of jobs you can complete, on a new line.

SAMPLE INPUT:
3
2
1 4
1 2
2
2 3
1 2
3
1 4
2 3
1 2
SAMPLE OUTPUT:
1
2
2

For the first test case, you can only complete one of the jobs. After completing one job, it will then be time 22 or later, so it is too late to start the other job, which must be started at time 11 or earlier.

For the second test case, you can start the second job at time 00 and finish at time 22, then start the first job at time 22 and finish at time 55.

SCORING:

  • Inputs 2: Within the same test case, all titi are equal.
  • Inputs 3-4: N≤2000N≤2000, si,ti≤2000si,ti≤2000
  • Inputs 5-8: N≤2000N≤2000
  • Inputs 9-16: No additional constraints.

从第三题开始,tldr每个工作有一个截止时间但是必须从si开始,已知时长ti,不能同时做很多工作,接着就是解题目标,求出最多能完成多少工作。所以是很明显的贪心问题。首先选择为每个工作的开始和时长做排序,(si+ti)再检查每个工作是否可以跟前者确定的基础上完成。

错误答案是土使用dp方法但是会超时:

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Job {
    long long start, time;
};

int solve() {
    int n;
    cin >> n;
    
    vector<Job> jobs(n);
    for(int i = 0; i < n; i++) {
        cin >> jobs[i].start >> jobs[i].time;
    }
     
    vector<int> dp(n + 1, 0);
     
    for(int i = 0; i < n; i++) { 
        for(long long start = 0; start <= jobs[i].start; start++) {
            long long finish = start + jobs[i].time;
            int count = 1;
             
            for(int j = 0; j < n; j++) {
                if(j != i && finish <= jobs[j].start) {
                    long long next_finish = jobs[j].start + jobs[j].time;
                    count++;
                    finish = next_finish;
                }
            }
            dp[i] = max(dp[i], count);
        }
    }
    
    int result = 0;
    for(int i = 0; i < n; i++) {
        result = max(result, dp[i]);
    }
    return result;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    int t;
    cin >> t;
    
    while(t--) {
        cout << solve() << "\n";
    }
    
    return 0;
}

优化v1:

第一步,最重要的是知道sort的过程,这个版本只采用了start time si排序,接下来要确保完成工作的顺序是si+ti

#include <bits/stdc++.h>
#include <climits>
using namespace std;

using ll = long long;

int main() {
	cin.tie(0)->sync_with_stdio(0);
	int T;
	cin >> T;
	for (int t = 0; t < T; ++t) {
		int N;
		cin >> N;
		vector<pair<ll, ll>> tasks;
		for (int n = 0; n < N; ++n) {
			ll s, t;
			cin >> s >> t;
			tasks.push_back({s, t});
		}
		sort(begin(tasks), end(tasks));
		ll time_so_far = 0;
		int ans = 0;
		for (auto [s, t] : tasks) {
			if (time_so_far <= s) {
				++ans;
				time_so_far += t;
			}
		}
		cout << ans << "\n";
	}
}
#include <bits/stdc++.h>
#include <climits>
using namespace std;

using ll = long long;

int main() {
	cin.tie(0)->sync_with_stdio(0);
	int T;
	cin >> T;
	for (int t = 0; t < T; ++t) {
		int N;
		cin >> N;
		vector<pair<ll, ll>> tasks;
		for (int n = 0; n < N; ++n) {
			ll s, t;
			cin >> s >> t;
			ll d = s + t;
			tasks.push_back({d, t});
		}
		sort(begin(tasks), end(tasks));
		vector<ll> dp{0};
		for (auto [d, t] : tasks) {
			dp.push_back(LLONG_MAX);
			for (int i = size(dp) - 2; i >= 0; --i)
				dp.at(i + 1) = min(dp.at(i + 1), dp.at(i) + t);
			while (dp.back() > d) dp.pop_back();
		}
		cout << size(dp) - 1 << "\n";
	}
}

要获取USACO 2024年12月青铜组奶酪块题目的具体内容、解题思路和代码实现,目前并没有公开的直接信息。通常,USACO竞赛题目会在竞赛结束一段时间后在其官方网站(http://usaco.org/ )上公布。 ### 一般查找竞赛题目信息的途径 - **官方网站**:USACO的官方网站是获取竞赛题目最权威的地方。在竞赛结束后,官方会将题目和测试数据等资源发布在网站上,并且会提供一些题解和分析。 - **竞赛论坛**:一些编程竞赛相关的论坛,如Codeforces、洛谷等,可能会有选手分享他们参加竞赛的经验、题目内容以及解题思路。 - **社交媒体和编程社区**:在Reddit、Stack Overflow等社区,可能会有关于该题目的讨论和解答。 ### 假设题目是路径规划类的一般解题思路和代码示例 如果这是一个类似路径规划的题目,比如需要在一个地图中找到最优路径来收集奶酪块,以下是一个简单的解题思路和Python代码示例。 #### 解题思路 - **建模**:将地图抽象为一个二维数组,奶酪块所在位置标记为特殊值。 - **搜索算法**:可以使用广度优先搜索(BFS)或深度优先搜索(DFS)来遍历地图,找到收集所有奶酪块的最短路径。 - **优化**:如果地图较大,可以使用A*算法等启发式搜索算法来提高搜索效率。 #### 代码示例 ```python from collections import deque # 定义地图和奶酪块位置 grid = [ [0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0] ] # 定义四个方向 directions = [(0, 1), (0, -1), (1, 0), (-1, 0)] # 广度优先搜索函数 def bfs(start, targets): queue = deque([(start, 0, set())]) visited = set() while queue: (x, y), steps, collected = queue.popleft() if collected == targets: return steps state = (x, y, frozenset(collected)) if state in visited: continue visited.add(state) for dx, dy in directions: new_x, new_y = x + dx, y + dy if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]): new_collected = collected.copy() if grid[new_x][new_y] == 1: new_collected.add((new_x, new_y)) queue.append(((new_x, new_y), steps + 1, new_collected)) return -1 # 找到所有奶酪块的位置 targets = set() for i in range(len(grid)): for j in range(len(grid[0])): if grid[i][j] == 1: targets.add((i, j)) # 假设起点为(0, 0) start = (0, 0) result = bfs(start, targets) print("最小步数:", result) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值