Codeforces Round #610 (Div. 2) C. Petya and Exam (贪心)
-
题意:你要参加一场考试,考试持续时间为\(T\),有两类题目简单题和难题,做一道简单题要花\(a\)分钟,难题要\(b\)分钟,每道题目都有一个强制时间\(t_i\),当考试时间为\(s\)时,且\(s\ge t_i\),假如你这时离开考试并且第\(i\)题没有写出来的话,你将得到\(0\)分,你可以在任意时刻离开考试,如果此时考试时间没有达到\(t_i\)或者你已经把第\(i\)题写完的话,将会得到你写完的题的数目的分数.注意,在到达\(t_{i+1}\)之前,这段时间我们可以随便利用.
-
题解:贪心,先将题目按\(t_i\)进行排序,然后我们遍历,假设我们遍历到第\(i\)个题目时,我们不想达到强制时间\(t_i\),所以此时最近的时间是\(t_i-1\),因为是按\(t_i\)升序的,所以前面\(i-1\)个题目我们必须要写完,然后剩下的时间可以先写简单题再写难题贪心的搞.
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} #define int long long struct misaka{ int op; int t; bool operator < (const misaka &mikoto) const{ if(t!=mikoto.t) return t<mikoto.t; return op<mikoto.op; } }e[N]; signed main(){ ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int _; cin>>_; while(_--){ int n,T,a,b; cin>>n>>T>>a>>b; int cnt_a=0,cnt_b=0; rep(i,1,n){ cin>>e[i].op; if(e[i].op==0) cnt_a++; else cnt_b++; } rep(i,1,n) cin>>e[i].t; sort(e+1,e+1+n); int d_a=0,d_b=0; int ans=0; e[n+1].t=T+1; rep(i,1,n+1){ ll cur=d_a*a+d_b*b; int rest=e[i].t-1-cur; //e[i].t-1表示我不用强制写这一题,但是前面的题目必须要强制写完,rest表示剩余的时间,我们可以随便利用. if(rest>=0){ int r_a=min(rest/a,cnt_a-d_a); rest-=r_a*a; int r_b=min(rest/b,cnt_b-d_b); ans=max(ans,d_a+d_b+r_a+r_b); } if(e[i].op==0) d_a++; else d_b++; } cout<<ans<<'\n'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮