B、Getting Points
跳转原题点击此:该题地址
1、题目大意
Monocarp为了完成总共n天的某学期的p学分任务。Monocarp每天可以选择两种度过方式:上一次课和完成最多两个任务 或者 休息一天。其中上课获得l学分,每个任务获得t学分,其中任务不可以重复接取,并且每周获得一个新的任务(第一天获得第一个任务,第8天获得第二个任务,以此类推),每个任务接取后可以在任意一天完成。
Monocarp只想完成最低要求并获得最大休息天数,问如何安排学习任务可以获得最大休息天数。
2、题目解析
由于每个任务接取后可以在任意一天完成,所以我们可以倒着往前推,先按照每天上一次课和两个任务(如果有的话)算,如果学分还不够就不断地每天上课直至完成即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int T;
ll n, p, l, t; // 注意输入范围
int f[N];
void solve()
{
cin >> n >> p >> l >> t;
ll tasks = 0; // 计算该学期一共能有几个任务
if(n % 7 == 0)
tasks = n / 7;
else
tasks = n / 7 + 1;
ll tmp = tasks / 2;
//计算有多少个既能上课又能完成两个任务的天数
ll sum_day = tmp * t * 2 + l * tmp;
if(sum_day >= p) // 如果满学习的天数 >= 总学分
{
ll tmp1 = 2 * t + l;
if(p % tmp1 == 0) // 算只需要几个满任务天数
cout << n - (p / tmp1) << endl;
else
cout << n - (p / tmp1 + 1) << endl;
return;
}
p -= sum_day; // 满学习的总学分不足则用上课和多余的任务补足
if(tasks % 2 == 1) // 如果总任务是奇数,则最开始会有一个不算在那
{
if(p <= (l + t))
{
cout << n - (tmp + 1) << endl;
return;
}
p -= (l + t); // 剩余要求学分
tmp++;
}
// 如果任务都解决了学分还是不够,那就只能上课
if(p % l == 0)
cout << n - (tmp + p / l) << endl;
else
cout << n - (tmp + p / l + 1) << endl;
}
int main()
{
cin >> T;
while (T--)
{
solve();
}
return 0;
}
标签:tasks,天数,ll,codeforces,1902B,任务,学分,接取,div2 From: https://www.cnblogs.com/Tom-catlll/p/17932955.html