zoukankan      html  css  js  c++  java
  • Cooking Time

    Cooking Time 

     

     题意: 有n种调料放在冰箱,你最多能把k种调料放外面,你每次打开冰箱,可以拿出一种调料,同时也可以放回去一种调料,也可以不放回。 每组输入案例第一行为n,k,第二行为n种调料的编号(从1到1e9),需要调料的顺序是输入的循序,输出是最少要打开多少次。

    对于知道使用情况的置换算法,最优解是找一个最后需要使用的物品替换掉也就是,如果一个物品后面已经不需要用到,就要放回去了,当外面的物品达到了k个,此时某些情况我就得从外面中拿一个回去

    思路:
    离散化:看到a[i]比较大,而个数比较少,并且只需要知道相对编号就好,这时就想到了离散化
    next数组下一个相同值在哪个位置;
    last数组用来辅助next数组记录,一开始所有的last[a[i]]==inf,只要大于a[i]编号(a[i]的编号通过离散化只会最大从0~(n-1))就好了,所以这里我用了last[a[i]]=n;
    inqueue数组用来判断是否物品在外面(即在队列中)
    具体细节见代码

    AC_Code

     1 #include <cstring>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 #include <bits/stdc++.h>
     7 using namespace std;
     8 typedef long long ll;
     9 const int maxn=1e5+5;
    10 int a[maxn],b[maxn],nxt[maxn],last[maxn],inqueue[maxn];
    11 
    12 map<int,int>mp;
    13 struct node{
    14     int nxt,id;
    15     bool operator < (const node &rhs ) const {
    16         return nxt<rhs.nxt;         //按下一次需要的"时间"从大到小排序
    17     }
    18 };
    19 
    20 int main()
    21 {
    22     int t,n,k,ans;
    23     scanf("%d",&t);
    24     while( t-- ){
    25         ans=0;
    26         priority_queue<node>Q;
    27         memset(inqueue,0,sizeof(inqueue));
    28         mp.clear();
    29 
    30         int cnt=0;
    31         scanf("%d%d",&n,&k);
    32 //        for(int i=0;i<n;i++){       //离散化
    33 //            scanf("%d",&a[i]);
    34 //            if( !mp.count(a[i])){
    35 //                mp[a[i]]=cnt++;
    36 //            }
    37 //            a[i]=mp[a[i]];
    38 //            last[a[i]]=n;
    39 //        }
    40 
    41         for(int i=0;i<n;i++){       //这种离散化方式更快
    42             scanf("%d",&a[i]);
    43             b[i]=a[i];
    44         }
    45         sort(b,b+n);
    46         int reu=unique(b,b+n)-b;
    47         for(int i=0;i<n;i++){
    48             a[i]=lower_bound(b,b+reu,a[i])-b;
    49             last[a[i]]=n;
    50         }
    51         for(int i=n-1;i>=0;i--){    //设定next
    52             nxt[i]=last[a[i]];
    53             last[a[i]]=i;
    54         }
    55 
    56         for(int i=0;i<n;i++){
    57             if(inqueue[a[i]]){            //如果要拿出的物品已经外面有了,那就把这个也压入队列,
    58                                           //因为next值发生了变化,也要更新。这是a[i]最新的next值
    59                 Q.push((node){nxt[i],a[i]});
    60                 continue;
    61             }
    62             else if( k ){                //在外面的物品不够,直接拿出来
    63                 Q.push((node){nxt[i],a[i]});
    64                 inqueue[a[i]]=1;
    65                 k--;
    66                 ans++;
    67             }
    68             else{                       //在外面的物品够了,则要进行放进去,拿出来的操作
    69                 node x=Q.top();
    70                 Q.pop();
    71                 inqueue[x.id]=0;
    72                 Q.push((node){nxt[i],a[i]});
    73                 inqueue[a[i]]=1;
    74                 ans++;
    75             }
    76         }
    77         printf("%d
    ",ans);
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    [LeetCode] 174. Dungeon Game 地牢游戏
    [LeetCode] Binary Search Tree Iterator 二叉搜索树迭代器
    [LeetCode] Excel Sheet Column Title 求Excel表列名称
    [LeetCode] Excel Sheet Column Number 求Excel表列序号
    [LeetCode] 179. Largest Number 最大组合数
    Camera Calibration and 3D Reconstruction
    [LeetCode] 172. Factorial Trailing Zeroes 求阶乘末尾零的个数
    [LeetCode] Find Peak Element 求数组的局部峰值
    Medical Image Processing Conference and Journal 医学图像处理会议与期刊
    [LeetCode] 144. Binary Tree Preorder Traversal 二叉树的先序遍历
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12269410.html
Copyright © 2011-2022 走看看