2 条题解
-
18
按照管理员的思路自己写了一个,开启O2优化后大概在850ms,看了一下提交记录属于中档水平,满意了
#include <iostream> #include <queue> using namespace std; queue<pair<int,int>> b; bool on_floor[100005]; struct cmp{ bool operator()(pair<int,int> x,pair<int,int> y) { return x.second<y.second; } }; priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> floor; int main() { int n,k,p,ans=0,floor_size=0; cin>>n>>k>>p; queue<int> temp1; queue<int> temp2[100005]; for(int i=1;i<=p;i++) { int x; cin>>x; temp1.push(x); temp2[x].push(i); } for(int i=1;i<=n;i++) temp2[i].pop(); for(int i=1;i<=p;i++) { if(temp2[temp1.front()].size()==0) b.push(make_pair(temp1.front(),p+1)); else { b.push(make_pair(temp1.front(), temp2[temp1.front()].front())); temp2[temp1.front()].pop(); } temp1.pop(); } for(int i=1;i<=p;i++) { if(!on_floor[b.front().first]) { if(floor_size==k) { while(!on_floor[floor.top().first]) floor.pop(); on_floor[floor.top().first]=false; } else floor_size++; floor.push(b.front()); on_floor[b.front().first]=true; ans++; } else { floor.push(b.front()); } b.pop(); } cout<<ans; }
-
15
被放回架子的玩具,在下次想玩时,一定需要重新从架子上拿下来,而这件事越晚发生越有利,因此可以采用这样的贪心策略:每次需要把玩具放回架子时,都选择下次被需要的时间最晚的玩具。(以后不再需要的,可以把下次被需要的时间设为一个大于10000的数)
a[i]表示第i个被需要的玩具,nxt[i]表示它下次被需要的时间。在求nxt数组的时候,可以倒序循环,用pos[x]表示x号玩具下次出现的时间,每次把nxt[i]赋值为pos[a[i]]即可。
维护一个优先队列,存放当前在地上的每一个玩具下次被需要的时间。每次需要把玩具放回架子时,取出队头元素。
使用数组inq维护每个玩具当前是否在地上,如果当前被需要的玩具在地上,那么就不需要取出队头。此时需要注意更新这件玩具下次被需要的时间,可以直接把新的时间加入队列。但是这样会导致队列里存在多个时间对应同一件玩具,对于这种情况,可以在把新的时间加入队列的时候,让k加1,以容纳多余的时间。而在取出队头的时候,通过inq检查它是否在队列里,如果已经不在,说明之前已经让这个玩具放回架子了,忽略这个时间,并让k减1。
统计把玩具拿到地上的次数即是最终答案。
核心代码
for (int i = 1; i <= 100000; i++) {//最初把所有玩具下次出现的时间设为大于10000的数 pos[i] = p + i; a[p + i] = i; } for (int i = p; i >= 1; i--) {//计算nxt数组 nxt[i] = pos[a[i]]; pos[a[i]] = i; } for (int i = 1; i <= p; i++) { if (inq[a[i]]) {//如果玩具已经在地上,就更新下次出现的时间,并让k加1 q.push(nxt[i]); k++; continue; } if (q.size() >= k) {//如果地上已经满了,就挑一个放回去 while (q.size() > 0 && !inq[a[q.top()]]) {//这里是处理一个玩具多次进入队列的情况 q.pop(); k--; } int x = q.top(); q.pop(); inq[a[x]] = false; } q.push(nxt[i]);//把当前需要的玩具拿到地上 inq[a[i]] = true; ans++; }
- 1
信息
- ID
- 258
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 795
- 已通过
- 324
- 上传者