URAL 1303 Minimal Coverage
思路:
dp+贪心,然后记录路径
mx[i]表示从i开始最大可以到的位置
sufmx[i]表从1-i的某个位置开始最大可以到达的位置
比普通的贪心效率要高很多
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mp make_pair #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; int l[N],r[N]; int mx[N],sufmx[N]; int id[N],iid[N]; vector<int>ans; int main(){ ios::sync_with_stdio(false); cin.tie(0); int m,L,R; while(cin>>m){ int c=0; mem(mx,-1); mem(id,-1); mem(iid,-1); ans.clear(); while(cin>>L>>R){ if(L==0&&R==0)break; c++; l[c]=L; r[c]=R; if(R>=0){ if(L<=0)L=0; if(R>mx[L])mx[L]=R,id[L]=c; } } sufmx[0]=mx[0]; iid[0]=id[0]; for(int i=1;i<=5e4;i++) { if(mx[i]>sufmx[i-1])sufmx[i]=mx[i],iid[i]=id[i]; else sufmx[i]=sufmx[i-1],iid[i]=iid[i-1]; } c=0; bool f=false; while(true){ if(sufmx[c]>=m){ ans.pb(c); break; } if(sufmx[c]>c){ ans.pb(c); c=sufmx[c]; } else { f=true; break; } } if(f){ cout<<"No solution"<<endl; continue; } cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++)cout<<l[iid[ans[i]]]<<' '<<r[iid[ans[i]]]<<endl; } return 0; }