CSP2021-S T1 廊橋分配
阿新 • • 發佈:2021-11-01
這其實是一道貪心的題目,然而官方資料很水導致n^2也能卡過
題目廊橋分配
答案要的是分配出的停放飛機的最大值,但是我們並不知道哪一種方法最優,所以我們可以把國內機場和國際機場分配x個廊橋時的最大停放飛機求出來,然後從分配機場數0到n列舉一遍求出最大值。
至於求解廊橋裡的飛機停放數目,則可以建一個優先佇列和一個廊橋陣列來求解。
而優化程式碼則是建立兩個優先佇列,一個是為了存放能進入的廊橋的標號,一個是為了存放最後離開的時間,與一直到達時間作為比較。
點選檢視程式碼
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cstdlib> #include<queue> using namespace std; #define MA 100005 int n,m1,m2; int pm1[MA]={0},tt1=0; int pm2[MA]={0},tt2=0; int en1[MA]={0},en2[MA]={0}; int as1[MA]={0},as2[MA]={0}; struct node1 { int fr,to; bool operator < (const node1 x)const { return fr>x.fr; } }; struct node2 { int to,num; bool operator < (const node2 x)const { return to>x.to; } }; priority_queue<node1>s1; priority_queue<node2>s2; bool cmp(int x,int y) { return x>y; } void rd1(int m,int &tot) { int i; int fr,to; while(!s1.empty()) s1.pop(); // while(!s2.empty()) // s2.pop(); for(i=1;i<=m;++i) { scanf("%d%d",&fr,&to); s1.push((node1){fr,to}); } node1 x; //node2 y; //int num; bool flag; while(!s1.empty()) { x=s1.top(); s1.pop(); //printf("[%d,%d]\n",x.fr,x.to); //flag=0; for(i=1;i<=tot;++i) if(x.fr>=en1[i]) { en1[i]=x.to; ++pm1[i]; //flag=1; break; } if(i>tot) { ++tot; ++pm1[tot]; en1[tot]=x.to; } //printf("%d %d]\n",i,tot); } //sort(pm1+1,pm1+1+m,cmp); for(i=1;i<=tt1;++i) { as1[i]=as1[i-1]+pm1[i]; } return; } void rd2(int m,int &tot) { int i; int fr,to; while(!s1.empty()) s1.pop(); // while(!s2.empty()) // s2.pop(); for(i=1;i<=m;++i) { scanf("%d%d",&fr,&to); s1.push((node1){fr,to}); } node1 x; //node2 y; //int num; bool flag; while(!s1.empty()) { x=s1.top(); s1.pop(); //printf("<>%d %d\n",x.fr,x.to); //flag=0; for(i=1;i<=tot;++i) if(x.fr>=en2[i]) { en2[i]=x.to; ++pm2[i]; //flag=1; break; } if(i>tot) { ++tot; ++pm2[tot]; en2[tot]=x.to; } } //sort(pm2+1,pm2+1+m,cmp); for(i=1;i<=tt2;++i) { as2[i]=as2[i-1]+pm2[i]; } return; } void print() { int i; puts(""); for(i=1;i<=tt1;++i) { printf("%d ",pm1[i]); } puts(""); puts(""); } int main() { //freopen("airport.in","r",stdin); //freopen("airport.out","w",stdout); //int n,m1,m2; scanf("%d%d%d",&n,&m1,&m2); rd1(m1,tt1); rd2(m2,tt2); int ans=0,i; for(i=tt1+1;i<=n;++i) { as1[i]=as1[tt1]; } for(i=tt2+1;i<=n;++i) { as2[i]=as2[tt2]; } //print(); for(i=0;i<=n;++i) { ans=max(as1[i]+as2[n-i],ans); //printf("%d\n",ans); //printf("[%d,%d]\n",as1[i],as2[i]); } printf("%d\n",ans); return 0; }
點選檢視程式碼
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cstdlib> #include<queue> using namespace std; #define MA 100005 int n,m1,m2; int pm1[MA]={0},tt1=0; int pm2[MA]={0},tt2=0; int en1[MA]={0},en2[MA]={0}; int as1[MA]={0},as2[MA]={0}; struct node1 { int to,fr; }; struct node2 { int to,num; bool operator < (const node2 x)const { return to>x.to; } }; priority_queue<node2>s1; priority_queue< int,vector<int>,greater<int> >s2; bool cmp(int x,int y) { return x>y; } bool cmp2 (node1 x,node1 y) { return x.fr<y.fr; } node1 y[MA]; void rd(int m,int &tot,int *as) { int i; int fr,to; while(!s1.empty()) s1.pop(); while(!s2.empty()) s2.pop(); for(i=1;i<=m;++i) { scanf("%d%d",&y[i].fr,&y[i].to); s2.push(i); } sort(y+1,y+1+m,cmp2); int sz=0; for(i=1;i<=m;++i) { if(sz) { while(sz && y[i].fr>s1.top().to) { --sz; s2.push(s1.top().num); s1.pop(); } } if(!s2.empty()) { tot=max(tot,s2.top()); ++as[s2.top()]; s1.push((node2){y[i].to,s2.top()}); s2.pop(); ++sz; } } for(i=1;i<=tot;++i) { as[i]=as[i-1]+as[i]; } return; } void print() { int i; puts(""); for(i=1;i<=tt1;++i) { printf("%d ",pm1[i]); } puts(""); puts(""); } int main() { //freopen("airport.in","r",stdin); //freopen("airport.out","w",stdout); scanf("%d%d%d",&n,&m1,&m2); rd(m1,tt1,as1); rd(m2,tt2,as2); int ans=0,i; for(i=tt1+1;i<=n;++i) { as1[i]=as1[tt1]; } for(i=tt2+1;i<=n;++i) { as2[i]=as2[tt2]; } //print(); for(i=0;i<=n;++i) { ans=max(as1[i]+as2[n-i],ans); } printf("%d\n",ans); return 0; }