P3419 [POI2005]SAM-Toy Cars
阿新 • • 發佈:2020-07-21
--------------------------------
非常顯然的貪心思路就是能放就放,放滿了然後把下一次使用間隔最久的拿走、
但是這樣會有一個問題,如果它已經進去了怎麼辦,
直接continue會wa掉,因為即使已經有了,我們還是應該更新一下下一個的值(易證)
那麼該怎麼辦呢
if(pl[p[i]]){ x.id=p[i]; x.nex=nex[i]; q.push(x); k++; continue; }
這樣擴大了地板,然後把原來的放到了一個永遠不會被訪問的部分,這樣就對了
---------------------------------------
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> using namespace std; int n,k; struct to{ int id; int nex; friend bool operator < (to a,to b){return a.nex<b.nex;//我一直很奇怪為什麼這是反的 } } x; priority_queue <to>q; int nex[500101],last[500101]; int p[500011]; int pp; int cnt; int pl[500101]; int main(){ scanf("%d%d%d",&n,&k,&pp); for(int i=1;i<=pp;++i){ scanf("%d",&p[i]); nex[last[p[i]]]=i; last[p[i]]=i; }//尋找下一個 for(int i=1;i<=n;++i){ nex[last[i]]=0x3f3f3f; }//處理下最後的部分 for(int i=1;i<=pp;++i){ if(pl[p[i]]){ x.id=p[i]; x.nex=nex[i]; q.push(x); k++; continue; } if(q.size()<k){//能放就放,除非已有 x.nex=nex[i]; x.id=p[i]; q.push(x); cnt++; pl[p[i]]=1; }else{//先拿再放 x=q.top(); q.pop(); pl[x.id]=0; x.nex=nex[i]; x.id=p[i]; q.push(x); cnt++; pl[x.id]=1; } } cout<<cnt; return 0; }
多組資料版
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; int n,k; int h; struct to{ int id; int nex; friend bool operator < (to a,to b){ return a.nex<b.nex; } } x; priority_queue <to>q; int nex[500101],last[500101]; int p[500011]; int pp; int cnt; int pl[500101]; int main(){ scanf("%d",&h); for(int j=1;j<=h;++j){ memset(p,0,sizeof(p)); memset(nex,0,sizeof(nex)); memset(last,0,sizeof(last)); memset(pl,0,sizeof(pl)); cnt=0; while(!q.empty()) q.pop(); scanf("%d%d%d",&n,&k,&pp); for(int i=1;i<=pp;++i){ scanf("%d",&p[i]); nex[last[p[i]]]=i; last[p[i]]=i; } for(int i=1;i<=n;++i){ nex[last[i]]=0x3f3f3f; } for(int i=1;i<=pp;++i){ if(pl[p[i]]){ x.id=p[i]; x.nex=nex[i]; q.push(x); k++; continue; } if(q.size()<k){ x.nex=nex[i]; x.id=p[i]; q.push(x); cnt++; pl[p[i]]=1; }else{ x=q.top(); q.pop(); pl[x.id]=0; x.nex=nex[i]; x.id=p[i]; q.push(x); cnt++; pl[x.id]=1; } } cout<<cnt<<endl; } return 0; }