C. Petya and Exam
题目链接
题意
你去参加考试,考试有两类题型,简单题和难题,简单题需要a时间解决出来,难题需要b时间解决出来,每道题到一定时时间会变成必做题,在这之前时非必做题,如果必做题没有写那么你将得到零分,问最多能得到多少分。
思路
能做简单题,先做简单题,但还要考虑时间限制,所以先将时间做一个从大到小的排序,最优的解法是什么呢,在这道题即将变到必做题的前一秒钟交卷,这样就能得到最多的分数,那么我在做每道题之前,先试探一下,将限制时间提前一秒钟去做当前问题,在还有剩余时间的同时去解决其题目,然后一直维护一个最大值。
通过代码
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
using namespace std;
#define ll long long
#define sl(n) scanf("%lld",&n)
#define pl(n) printf("%lld",n)
#define sdf(n) scanf("%lf",&n)
#define pdf(n) printf("%.lf",n)
#define pE printf("\n")
#define ull unsigned long long
#define pb push_back
#define pre(n) for(ll i=1;i<=n;i++)
#define rep(n) for(ll i=n;i>=1;i--)
#define ph push
#define pi pair<ll,ll>
#define fi first
#define se second
struct node
{
ll flag, limit;
} a[200010];
bool cmp(node a, node b)
{
if (a.limit == b.limit)return a.flag < b.flag;
return a.limit < b.limit;
}
int main()
{
ll _,i;
sl(_);
while (_--)
{
ll n, t, easy, hard, cnta = 0, cntb = 0;
sl(n), sl(t), sl(easy), sl(hard);
pre(n)
{
sl( a[i].flag );
if (a[i].flag == 0)cnta++;
else cntb++;
}
pre(n)sl(a[i].limit);
sort(a + 1, a + n + 1, cmp);
a[n + 1].limit = t + 1;
ll ans = 0, cnt_a = 0, cnt_b = 0;
for (i = 1; i <= n+1; i++)
{
ll cur = cnt_a * easy + cnt_b * hard;
ll rest = a[i].limit - cur - 1;
if (rest >= 0)
{
ll q = min(rest / easy, cnta - cnt_a);
rest -= q * easy;
ll p = min(rest / hard, cntb - cnt_b);
ans = max(ans, p + q + cnt_a + cnt_b);
}
if (a[i].flag)cnt_b++;
else cnt_a++;
}
cout << ans << endl;
}
return 0;
}