zoukankan      html  css  js  c++  java
  • 饥饿的牛 线性dp内的区间

    饥饿的牛

    牛在饲料槽前排好了队。饲料槽依次用1到N(1<=N<=100000)编号。每天晚上,一头幸运的牛根据约翰的规则,吃其中一些槽里的饲料。

      约翰提供B个区间的清单。一个区间是一对整数start-end,1<=start<=end<=N,表示一些连续的饲料槽,比如1-3,7-8,3-4等等。牛可以任意选择区间,但是牛选择的区间不能有重叠。
    当然,牛希望自己能够吃得越多越好。给出一些区间,帮助这只牛找一些区间,使它能吃到最多的东西。
    在上面的例子中,1-3和3-4是重叠的;聪明的牛选择{1-3,7-8},这样可以吃到5个槽里的东西。

    输入
    第一行,整数B(1<=B<2000)
    第2到B+1行,每行两个整数,表示一个区间,较小的端点在前面。

    输出
    仅一个整数,表示最多能吃到多少个槽里的食物。

    样例
    输入:
    3
    1 3
    7 8
    3 4
    输出:
    5
    说明:数据前10组为小数据,后10组为大数据,N〈=10000000;B〈=100000

    然后那到这道题就有两个想法

    1.设f(i)为到前i个点能得到的最大区间

    {

      如果没有到i的区间f(i)=f(i-1);

      否则f(i)=f(所有到i的开始位置的点-1)+区间和;

      f(i)=max(f(i-1),f(i));

    }
    然后用链表优化时间

    #include<cstdio>
    #include<algorithm>
    #define N1 100000+1
    #define N2 2000+1
    using namespace std;
    struct edge{
        int next;
        int to;
    };
    int num,head[N1];
    edge e[N2];
    void add(int from,int to)
    {
        e[++num].next=head[from];
        e[num].to=to;
        head[from]=num;
    }
    int f[N1];
    bool flag[N1];
    int main()
    {
        int b,x,y,n=0;
        scanf("%d",&b);
        for(int i = 1;i<=b;i++)
        {
            scanf("%d%d",&x,&y);
            add(y,x);
            if(y>n)n=y;
            flag[y]=1;
        }
        for(int i=1;i<=n;i++)
        {
            f[i]=f[i-1];
            if(!flag[i])continue;
            else{
                for(int j=head[i];j;j=e[j].next)
                {
                    int v=e[j].to;
                    f[i]=max(f[i],f[v-1]+(i-v+1));
                }
            }
        }
        printf("%d",f[n]);
        return 0;
    }

    2.设f(i)为前i个区间能获得的最大区间值

    貌似要以区间右端点排序

    1.f(i)=f(i-1)

    2.f(i)=f(不在这个区间内,却最靠近这个区间的左断点)+这个区间的值

    f(i)=max{1,2};

    时间复杂度O(nlogn);

    空间复杂度O(n);

    因为排序,所以可以用二分查找优化,否则超时

    #include<cstdio>
    #define maxn 100000+2
    using namespace std;
    int f[maxn],b;
    struct s_p
    {
    	int s,e;
    	bool operator <(s_p b)
    	{
    		return s<b.s;
    	}
    }data[maxn];
    void change(s_p &a,s_p &b)
    {
    	s_p t=a;a=b;b=t;
    }
    void sort(int a,int b)
    {
    	if(a==b)return;
    	s_p val=data[(a+b)/2];
    	int i=a-1,j=b+1;
    	while(1)
    	{
    	  do i++;while(data[i]<val);
    	  do j--;while(val<data[j]);
    	  if(i>=j)break;
    	  change(data[i],data[j]);
        }
        sort(a,j);
        sort(j+1,b);
    }
    int find(int a,int B,int c)
    {
    	if(a==B)
    	{
    		if(data[a].s>=c)return a;
    		return b+1;
    	}
    	int mid=(a+B)/2;
    	if(c<=data[mid].s)return find(a,mid,c);
    	return find(mid+1,B,c);
    }
    int main()
    {
    //	freopen("10034.in","r",stdin);
    //	freopen("10034.out","w",stdout);
    	scanf("%d",&b);
    	for(int i=1;i<=b;i++)
    	scanf("%d%d",&data[i].s,&data[i].e);
    	sort(1,b);
    	for(int i=b;i>=1;i--)
    	{
    		f[i]=f[i+1];
    		int t=find(1,b,data[i].e+1);
    		if(f[i]<f[t]+data[i].e-data[i].s+1)f[i]=f[t]+data[i].e-data[i].s+1;
    	}
    	printf("%d",f[1]);
    	fclose(stdout);
    	return 0;
    }
    

      

  • 相关阅读:
    在Visual Studio 2013中修改远程Git服务器的地址
    自定义TFS工作项“所有链接”列表中的列
    在权限受限制的AD域环境中部署SQL Server AlwaysOn高可用性
    spring boot常用注解
    在线编辑器(WangEditor)
    报表生成(POI,jquery.table2excel.js,Echarts)
    java 相关书籍介绍
    poj2456 Aggressive cows
    poj1064 Cable master
    洛谷P1396 营救
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7562492.html
Copyright © 2011-2022 走看看