zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 3:D. Gadgets for dollars and pounds(二分答案+贪心)

    看了菊苣的理解才知道怎么写。。根本没思路啊一开始。。。

    天数肯定在1~n之间,二分答案。

    可以用保存前i天的最低美元和英镑汇率,没有规定哪天买,每天也没有购买数量限制,所以二分出一个答案mid的后,就在前mid天中汇率最低的时候一次性购入最便宜的就行了,judge一下总花费

    打印答案的时候以ans为结果,再模拟一遍就好

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"vector"
    #define ll long long
    
    using namespace std;
    const int MAXN = 200050;
    const int INF = 0x3f3f3f3f;
    ll n,m,k,s;
    ll d[MAXN],p[MAXN],mind[MAXN],minp[MAXN];
    int mindpos[MAXN],minppos[MAXN];
    struct node{
        ll c,o;
        node(){}
        node(ll a,ll b):c(a),o(b){}
    };
    
    vector<node> dd,pp;
    
    bool cmp(node a,node b){
        return a.c<b.c;
    }
    
    bool judge(ll x){
        ll tot=0,cnt=0;
        int i=0,j=0;
        while(cnt<k&&tot<=s){
            ll td=INF,tp=INF;
            if(i<dd.size()) td=mind[x]*dd[i].c;
            if(j<pp.size()) tp=minp[x]*pp[j].c;
    
            if(td<tp){
                tot+=td;
                i++;
            }
            else{
                tot+=tp;
                j++;
            }
            cnt++;
        }
        if(tot>s) return false;
        return true;
    }
    
    void display(ll ans){
        if(ans==-1) return ;
        ll cnt=1;
        int i=0,j=0;
        while(cnt<=k){
            ll td=INF,tp=INF;
            if(i<dd.size()) td=mind[ans]*dd[i].c;
            if(j<pp.size()) tp=minp[ans]*pp[j].c;
    
            if(td<tp)
                printf("%I64d %d
    ",dd[i++].o,mindpos[ans]);
            else
                printf("%I64d %d
    ",pp[j++].o,minppos[ans]);
            cnt++;
        }
    }
    
    int main(){
        //freopen("in.txt","r",stdin);
        scanf("%I64d%I64d%I64d%I64d",&n,&m,&k,&s);
        minp[0]=mind[0]=INF;
        for(int i=1;i<=n;i++) {
            scanf("%I64d",&d[i]);
            mind[i]=min(mind[i-1],d[i]);
            if(mind[i]!=mind[i-1]) mindpos[i]=i;
            else mindpos[i]=mindpos[i-1];
        }
        for(int i=1;i<=n;i++) {
            scanf("%I64d",&p[i]);
            minp[i]=min(minp[i-1],p[i]);
            if(minp[i]!=minp[i-1]) minppos[i]=i;
            else minppos[i]=minppos[i-1];
        }
        for(int i=1;i<=m;i++) {
            ll t,c;
            scanf("%I64d%I64d",&t,&c);
            if(t==1) {
                dd.push_back(node(c,i));
            }
            else pp.push_back(node(c,i));
        }
        sort(dd.begin(),dd.end(),cmp);
        sort(pp.begin(),pp.end(),cmp);
        //for(int i=1;i<=n;i++) cout<<mindpos[i]<<'	'<<minppos[i]<<endl;
    
        ll low=1,high=n,mid,ans=-1;
        while(low<=high){
            mid=(low+high)>>1;
            if(judge(mid)){
                ans=mid;
                high=mid-1;
            }
            else low=mid+1;
        }
        printf("%I64d
    ",ans);
        display(ans);
        return 0;
    }
    View Code
  • 相关阅读:
    InnoDB和MyISAM区别
    include和require的区别
    php的魔术方法
    php中heredoc的使用方法
    20条常见的编码陷阱
    php header 跳转
    php.ini设置详解
    session的实现原理 大网站应用应注意的问题
    Ruby on Rails 开发实践相关命令参考
    IBM WebSphere Portal6 最佳项目实践
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5064969.html
Copyright © 2011-2022 走看看