取尺法 和区间调度

来源:互联网 发布:服装软件有哪些 编辑:程序博客网 时间:2024/05/21 15:46

/*取尺法给定义一个数列 {An} 和整数S求出总和不小于S的连续子序列长度的最小值如果解不存在 输出0EG:输入:N=5;S=15;A={5,1,3,5,10,7,4,9,2,8};输出 2  (5+10) 解 此题解法多种 取尺法可以将复杂度降到O(n)的级别 代码:*/# include <stdio.h># define min(a,b)((a)<(b)?(a):(b))# define MAX 100int main(){int A[MAX]={0},N,S,t,sum,i,ss,res;scanf("%d %d",&N,&S);for(i=0;i<N;i++)scanf("%d",&A[i]);    for(ss=sum=t=0,res=N+1;;){   while(t<N&&sum<S)   sum+=A[t++];   if(sum<S) break;        res=min(res,t-ss);sum-=A[ss++];}    printf("%d\n",res>N?0:res);  return 0;}
/*有n项工作,每项工作分别在时间开始,在时间结束。对于每项工作,你都可以选择参与与否。如果选择了参与,那么自始至终都必须全程参与。此外,参与工作的时间段不能重叠(闭区间)。你的目标是参与尽可能多的工作,那么最多能参与多少项工作?N∈[1,100000]  S,T∈[1,10^9] 解:最大区间调度问题。在此我们进行细分,将该问题命名为最多区间调度问题,因为该问题的目标是求不重叠的最多区间个数,而不是最大的区间长度和。最简单的区间调度问题,可以通过贪心算法求解,贪心策略:在可选的工作中,每次都选取结束时间最早的工作。EG:输入:N=5S={1,2,4,6,8}T={3,5,7,9,10}输出:3(选择1 3 5 工作)*/# include <stdio.h># define N 100void paixu(int A[][N],int n);//选择排序 当数量很大时 用快速排序 这里就不改了 void SWEP(int *a,int *b);//交换函数int A[2][N];int main(){int i,n,sum=0,t=0;//sum记录公祖豆儿数量 t记录结束时间    scanf("%d",&n);    for(i=0;i<n;i++)scanf("%d",&A[0][i]);//A[0]->Sfor(i=0;i<n;i++)scanf("%d",&A[1][i]);//A[1]->T    paixu(A,n);//排序时以A[1]为比较对象    for(i=0;i<N;i++){   if(t<A[0][i])   sum++;   t=A[1][i];}printf("%d",sum);return 0;}void paixu(int A[][N],int n)//就是对A[1][?]升序排列{int i,j,k;for(i=0;i<n-1;i++){   k=i;     for(j=i+1;j<n;j++) if(A[1][j]>A[1][k])     k=j; if(k!=i) {             SWEP(&A[0][i],&A[0][k]); SWEP(&A[1][i],&A[i][k]); }}}void SWEP(int *a,int *b){   int temp=*a;   *a=*b;   *b=temp;}



2 0
原创粉丝点击