贪心思路:对于a[i]尽可能多的取,然后再尽可能多的取a[i+1]
sum表示a[1]~a[i-1]取的总钱数,cnt表示总张数
对于a[i]取的张数x需要满足
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int q, n;
ll a[N], s;
pair<ll, ll> ans[N];
struct node {
ll q, ans, cnt;
int id;
bool operator<(const node &b) const {
return q < b.q;
}
} query[N];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);
a[n + 1] = 1e18 + 1;
scanf("%d", &q);
for (int i = 1; i <= q; i++)scanf("%lld", &query[i].q), query[i].id = i;
sort(query + 1, query + 1 + q);
ll s = 1e18;
ll sum = 0, res = 0;
int j = 1;
for (int i = 1; i <= n; i++) {
if ((s - sum) < a[i])break;
ll x = (a[i + 1] - sum - 1) / a[i];
while (j <= q && sum + a[i] * x >= query[j].q) {
ll k = (query[j].q - sum) / a[i];
query[j].cnt = res + k;
query[j].ans = sum + k * a[i];
j++;
}
if (j > q)break;
res += x;
sum += a[i] * x;
}
while (j <= q) {
query[j].cnt = res;
query[j].ans = sum;
j++;
}
for (int i = 1; i <= q; i++)
ans[query[i].id] = {query[i].ans, query[i].cnt};
for (int i = 1; i <= q; i++)
printf("%lld %lld\n", ans[i].first, ans[i].second);
return 0;
}
京公网安备 11010502036488号