Gadgets for dollars and pounds【CodeForces 609D】【二分答案+贪心】

版权声明:https://blog.csdn.net/qq_41730082 https://blog.csdn.net/qq_41730082/article/details/85245919

题目链接


  还是可以的一道题,但是多次写飙……也是醉了,题意就是给你N天,每天都有一个相对应的美元以及英镑的汇率,就是每单位钱需要多少卢比。然后,还有M个物品,他们有相应的价值:第一个数表示,它支持美元支付还是英镑支付——“1”代表美元、“2”代表英镑,然后是所需的对应货币的数量。我们要K个这样的物品,并且,我们有S个卢比(初始的时候),然后,我们可以用卢比去换钱,问:最早第几天的时候,我们可以拿齐K中物品。

  那么,我们可以二分答案,去假设第几天的时候会拿到K个物品,然后处理一下前缀最小值的货币汇率,因为我们可以最后一天再买所有的物品,之前只用囤钱就行了,所以,每个物品的哪天买的时间,可以都为期限时间(SPJ)。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include<time.h>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define efs 1e-7
#define son1 (j-1)>0? ans[i-1][j-1] : 0
#define son2 (j+1)<=M? ans[i-1][j+1] : 0
#define son3 (i-2)>0? ans[i-2][j] : 0
#define copppy(pr, ans) memcpy(pr, ans, sizeof(ans))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 2e5 + 7;
int N, M, K, need_D, need_P;   //Amer、US分别记录美元、英镑的前缀最小值,就是可以换钱的最小值,need_D和need_P分别记录需要美元和英镑的物品的数量
ll Amer[maxN], US[maxN], S;
pair<ll, int> vD[maxN], vP[maxN];
int day_D[maxN], day_P[maxN];   //改天对应的最优货币解
int used_D, used_P, ans_D, ans_P;
void init()
{
    Amer[0] = US[0] = Amer[N+1] = US[N+1] = INF;
    need_D = need_P = ans_D = ans_P = 0;
}
bool solve(int day)
{
    ll sum = 0;
    ll dollar = Amer[day], pound = US[day];
    int kk = min(K, need_D);    //用kk记录下使用美元的最大数量
    used_D = kk;
    for(int i=1; i<=kk; i++)
    {
        sum += dollar * vD[i].first;
    }
    int tot = K - kk;
    used_P = tot;
    for(int i=1; i<=tot; i++)
    {
        sum += pound * vP[i].first;
    }
    int pp = min(K, need_P);
    for(int i=tot+1; i<=pp; i++)
    {
        if(sum <= S) { ans_D = used_D; ans_P = used_P; return true; }
        if(kk == 0) break;
        sum += pound * vP[i].first;
        sum -= dollar * vD[kk--].first;
        used_P++;
        used_D--;
    }
    if(sum <= S) { ans_D = used_D; ans_P = used_P; return true; }
    return false;
}
void Print(int day)
{
    if(day <= 0) return;
    for(int i=1; i<=ans_D; i++) printf("%d %d\n", vD[i].second, day_D[day]);
    for(int i=1; i<=ans_P; i++) printf("%d %d\n", vP[i].second, day_P[day]);
}
int main()
{
    while(scanf("%d%d%d%lld", &N, &M, &K, &S)!=EOF)
    {
        init();
        for(int i=1; i<=N; i++)
        {
            ll e1; scanf("%lld", &e1);
            if(e1 < Amer[i-1])
            {
                day_D[i] = i;
                Amer[i] = e1;
            }
            else
            {
                day_D[i] = day_D[i-1];
                Amer[i] = Amer[i-1];
            }
        }
        for(int i=1; i<=N; i++)
        {
            ll e1; scanf("%lld", &e1);
            if(e1 < US[i-1])
            {
                day_P[i] = i;
                US[i] = e1;
            }
            else
            {
                day_P[i] = day_P[i-1];
                US[i] = US[i-1];
            }
        }
        for(int i=1; i<=M; i++)
        {
            int op; scanf("%d", &op);
            if(op == 1)
            {
                scanf("%lld", &vD[++need_D].first);
                vD[need_D].second = i;
            }
            else
            {
                scanf("%lld", &vP[++need_P].first);
                vP[need_P].second = i;
            }
        }
        sort(vD + 1, vD + 1 + need_D);
        sort(vP + 1, vP + 1 + need_P);
        int L = 1, R = N, ans = -1, mid = 0;
        while(L <= R)
        {
            mid = (L + R)/2;
            if(solve(mid)) { R = mid - 1; ans = mid; }
            else L = mid + 1;
        }
        if(ans == 0) ans = -1;
        printf("%d\n", ans);
        Print(ans);
    }
    return 0;
}
/*
10 10 10 1000000
836 842 645 671 499 554 462 288 89 104
880 722 623 651 591 573 154 532 136 59
1 47
1 169
2 486
1 262
2 752
2 498
2 863
2 616
1 791
1 656
 Answer:
 9
 1 9
 2 9
 4 9
 10 9
 9 9
 3 9
 6 9
 8 9
 5 9
 7 9
*/

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/85245919