http://acm.timus.ru/problem.aspx?space=1&num=1303
简单dp 排序枚举就可以 不过由于M最多可以是5000
所以需要用到一定的优化
比如说 既然要覆盖 0---m 那么在0左边的区间 和在m右边 的区间 和被其他区间包含的区间 都应该去掉
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include<set> #include<queue> #include<stack> #include<cmath> #define LL long long using namespace std; const int N=100005; const int INF=0x6fffffff; struct node { int x,y; }mem[N]; int f[N]; int sum[N]; int ans[N]; bool cmp(node a,node b) { if (a.x==b.x) return a.y>b.y; return a.x<b.x; } void Fans( int l, int n) { for ( int i=n;i>=1;--i) { ans[i]=l; l=f[l]; } } int main() { //freopen("data","r",stdin); int m; int x,y; scanf ( "%d" ,&m); int I=0; while ( scanf ( "%d %d" ,&x,&y)) { if (x==0&&y==0) break ; if ((x>=m&&y<=0)||(x==y)) continue ; mem[I].x=x;mem[I].y=y;++I; } sort(mem,mem+I,cmp); memset (sum,-1, sizeof (sum)); int k=-1; if (mem[0].x>0) { printf ( "No solution\n" ); return 0; } int n=I; I=0; for ( int i=0;i<n;++i) { int l=0; if (i>0&&mem[i].x!=mem[I-1].x) for (l=0;l<I;++l) { if (mem[l].x<=mem[i].x&&mem[i].y<=mem[l].y) break ; } if (l==I) {mem[I].x=mem[i].x;mem[I].y=mem[i].y;++I;} } for ( int i=0;i<I;++i) { int x=mem[i].x; int y=mem[i].y; if (i>0&&x==mem[i-1].x) continue ; if (x<=0) { sum[i]=1; f[i]=-1; if (y>=m&&(k==-1||sum[i]<sum[k])) { k=i; } } else { int temp=INF; int l=-1; for ( int j=0;j<i;++j) { if (sum[j]!=-1&&mem[j].y>=x&&sum[j]<temp) { temp=sum[j];l=j; } } if (l!=-1) { sum[i]=sum[l]+1; f[i]=l; if (y>=m&&(k==-1||sum[i]<sum[k])) { k=i; } } } } if (k==-1) printf ( "No solution\n" ); else { printf ( "%d\n" ,sum[k]); Fans(k,sum[k]); for ( int i=1;i<=sum[k];++i) { printf ( "%d %d\n" ,mem[ans[i]].x,mem[ans[i]].y); } } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步