题意:给定m个物品(编号从1-m)以及它们的种类和价格(美元和英镑),其中种类1意味着购买该物品需要美元,反之需要英镑。已知在n天里,每天都会有美元和英镑的兑换率a[i]和b[i],意味着用a[i]个burle可以换取1美元,英镑的兑换同理。现在你手上只有s个burle,你需要在n天里购买k个物品,要求每个物品只能买一次,问你最早在第几天可以完成任务,并输出购买方案。
先输出天数,下面k行每行输出两个数字:1,物品的编号 2,在第几天购买该物品。
坑死啊,一开始以为输出的第一个数字对应着1,2,3,4,5...k。WA了一次后实在找不到bug,换了输出就过了。。。
思路:分开种类1、2,升序排列后,预处理花费前缀和。每次二分找到兑换率最小的那一天,判断下就好了。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (200000+10)
#define MAXM (100000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
LL a[MAXN], b[MAXN];
struct Node{
LL cost; int id;
};
Node numd[MAXN], nump[MAXN];
bool cmp(Node a, Node b){
return a.cost < b.cost;
}
LL sumd[MAXN], sump[MAXN];
int top1, top2;
int dday, pday, dnum, pnum;
bool judge(int n, int k, LL total)
{
LL Md = INF, Mp = INF; int pd, pp;
for(int i = 1; i <= n; i++)
{
if(Md > a[i])
{
Md = a[i];
pd = i;
}
if(Mp > b[i])
{
Mp = b[i];
pp = i;
}
}
for(int i = 0; i <= top1; i++)
{
int j = k - i;
if(j > top2 || j < 0) continue;
//printf("-------------%lld %lld\n", sumd[i] * Md + sump[j] * Mp, total);
if(sumd[i] * Md + sump[j] * Mp <= total)
{
dnum = i; pnum = j;
dday = pd; pday = pp;
return true;
}
}
return false;
}
int main()
{
int n, m, k; LL s;
Ri(n); Ri(m); Ri(k); Rl(s);
for(int i = 1; i <= n; i++)
Rl(a[i]);
for(int i = 1; i <= n; i++)
Rl(b[i]);
top1 = top2 = 0;
for(int i = 1; i <= m; i++)
{
int t; LL d;
Ri(t), Rl(d);
if(t == 1)
numd[++top1].cost = d, numd[top1].id = i;
else
nump[++top2].cost = d, nump[top2].id = i;
}
sumd[0] = 0;
sort(numd+1, numd+top1+1, cmp);
for(int i = 1; i <= top1; i++)
sumd[i] = sumd[i-1] + numd[i].cost;
sump[0] = 0;
sort(nump+1, nump+top2+1, cmp);
for(int i = 1; i <= top2; i++)
sump[i] = sump[i-1] + nump[i].cost;
int l = 1, r = n, ans = 0, mid;
while(r >= l)
{
mid = (l + r) >> 1;
if(judge(mid, k, s))
{
ans = mid;
r = mid-1;
}
else
l = mid+1;
}
if(!ans)
Pi(-1);
else
{
Pi(ans);
for(int i = 1; i <= dnum; i++)
printf("%d %d\n", numd[i].id, dday);
for(int i = 1; i <= pnum; i++)
printf("%d %d\n", nump[i].id, pday);
}
return 0;
}