zoukankan      html  css  js  c++  java
  • CodeForce---Educational Codeforces Round 3 D. Gadgets for dollars and pounds 正题

    对于这题笔者无解,只有手抄一份正解过来了:

    基本思想就是 :

    • 二分答案,对于第x天,计算它最少的花费f(x),<=s就是可行的,这是一个单调的函数,所以可以二分。
    • 对于f(x)的计算,我用了nlog(n)的算法,遍历m个商品,用c[i]乘以前x天里,第t[i]种货币的最便宜的价格,存放到一个数组里,之后排序,计算前k个的和就是f(x)
    • 前x天里,第t[i]种货币的最便宜的价格是通过预处理得到的,很容易的计算一下前缀最小值就行了。

    贴代码吧:

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #include <algorithm> 
    using namespace std;
    typedef long long ll;
    typedef pair<ll,int> pii;
    #define fi first
    #define se second
    #define mp make_pair
    const int maxn = 200005;
    int a[maxn],b[maxn],t[maxn],c[maxn];
    int n,m,k,s;
    int am[maxn],bm[maxn];
    int ida[maxn],idb[maxn];
    const int inf = 0x3f3f3f3f;
    
    pii pli[maxn];
    int id[maxn];
    
    ll f(int x){
        ll ret = 0;
        for (int i=1;i<=m;i++){
            if (t[i] == 1){
                pli[i].fi = (ll)c[i] * (ll)am[x];
    
            }
            else{
                pli[i].fi = (ll)c[i] * (ll)bm[x];
            }
            pli[i].se = i;
        }
        sort(pli+1,pli+m+1);
        for (int i=1;i<=k;i++){
            ret += pli[i].fi;
        } 
    
        return ret;
    }
    
    
    int main(){
        cin>>n>>m>>k>>s;
        am[0] = bm[0] = inf;
        for (int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if (a[i] < am[i-1]){
                am[i] = a[i];
                ida[i] = i;
            }
            else{
                am[i] = am[i-1];
                ida[i] = ida[i-1];
            }
        }
        for (int i=1;i<=n;i++){
            scanf("%d",&b[i]);
            if (b[i] < bm[i-1]){
                bm[i] = b[i];
                idb[i] = i;
            }
            else{
                bm[i] = bm[i-1];
                idb[i] = idb[i-1];
            }
        }
        for (int i=1;i<=m;i++){
            scanf("%d%d",&t[i],&c[i]);
        }
    
        ll low,high,mid;
        low = 1,high = n;
        ll d = -1;
        while(low <= high){
            mid = (low + high) / (ll)2;
            if (f(mid) <= s){
                high = mid - 1;
                d = mid;
                for (int i=1;i<=k;i++){
                    id[i] = pli[i].se;
                }
            }
            else{
                low = mid + 1;
            }
        }
        cout << d <<"
    ";
        if (d == (ll)-1)
            return 0;
        int x = (int)d;
        for (int i=1;i<=k;i++){
            printf("%d %d
    ",id[i],t[id[i]]==1?ida[x]:idb[x]);
        }
    
        return 0;
    }
  • 相关阅读:
    Element-ui左侧菜单刷新依旧高亮显示当前菜单
    Element-ui表格单选
    Element-UI表格点击Popover 弹出框确定取消
    纯JS原生请求接口post方式
    Vue+Element-ui+二级联动封装组件
    Vue如何修改标题title呢?
    vue-cli3.0怎么修改端口?
    Element-ui上传文件(删除、添加、预览)
    关于Ubuntu的ifconfig命令出现SIOCSIFADDR系列错误
    关于keil 中出现“give arg types”
  • 原文地址:https://www.cnblogs.com/Bincoder/p/5064992.html
Copyright © 2011-2022 走看看