HDU2037 贪心 动归均可+证明
|
F[i] 前i个小时的最大观看数量
F[i]=MAX(F[i-1],F[A[k].s]) (当 A[k].e==i时)
不过动归这题有点坑。。。不一定是24小时 可能是100小时。。等等 完全等同于线段覆盖这题了
代码附上
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node { int s; int t; }node; node a[10001]; int F[25]; int cmp(const void *i,const void *j) { node *ii=(node *)i,*jj=(node *)j; if(ii->t!=jj->t) return ii->t-jj->t; else return ii->s-jj->s; } int max(int a,int b) { if(a>b) return a; else return b; } int main() { freopen("a.in","r",stdin); freopen("a.out","w",stdout); int n,i,j; while(scanf("%d",&n)!=EOF&&n!=0) { memset(F,0,sizeof(F)); memset(a,0,sizeof(a)); for(i=1;i<=n;i++) scanf("%d%d",&a[i].s,&a[i].t); qsort(a+1,n,sizeof(a[1]),cmp); j=1; for(i=0;i<=100;i++) { if(i!=0) F[i]=F[i-1]; for(;j<=n;j++) { if(a[j].t<i) {continue;} if(a[j].t>i) {break;} F[i]=max(F[i],F[a[j].s]+1); } } printf("%d\n",F[100]); } return 0; }
贪心证明(利用数学归纳法):
当i=1时
这两种情况 都显然选择 下面这种右端点靠后的情况 所以我们可以觉得贪心的策略是否是选择右端点小的
i=1时 此时为全局最优解
假设 i=k时 依旧为全局最优解
i=k+1时
因为这两个线段都不能与前面有交集 所以没有后效性 此时类似i=1 一样保持这样的贪心策略使得保持全局最优解
所以得证 以右端点排序 不断选择合理的右端点小的线段
代码如下
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node { int s; int t; }node; node a[10001]; int ans=0; int cmp(const void *i,const void *j) { node *ii=(node *)i,*jj=(node *)j; if(ii->t!=jj->t) return ii->t-jj->t; else return ii->s-jj->s; } int max(int a,int b) { if(a>b) return a; else return b; } int main() { freopen("a.in","r",stdin); freopen("b.out","w",stdout); int n,i,j,end; while(scanf("%d",&n)!=EOF&&n!=0) { ans=0;end=0; memset(a,0,sizeof(a)); for(i=1;i<=n;i++) scanf("%d%d",&a[i].s,&a[i].t); qsort(a+1,n,sizeof(a[1]),cmp); for(i=1;i<=n;i++) { if(a[i].s>=end) ans++,end=a[i].t; } printf("%d\n",ans); } return 0; }