zoukankan      html  css  js  c++  java
  • P1868 饥饿的奶牛

    永久打开的传送门

    (color{Red}{------------------分割线----------------------------})

    (感觉是非常巧妙的DP。。。。)

    (先按照区间右端点进行排序)

    (f[i]表示前i个区间中,最后一个区间选的i,最大有多少草)

    (f[i]=max(f[i-1],f[j]+a[i].tail-a[i].head+1);//j表示尾小于当前区间头且f最大的区间下标)

    (这是O(n^2)的,但是找j可以用二分优化成O(nlogn))(下面还有O(n)算法)$

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=150009;
    int n,f[maxn];
    struct p{
    	int x,y,val;
    }a[maxn];
    bool com(p a,p b){
    	return a.y<b.y;
    }
    int find(int l,int r,int key)
    {
    	int ans=0;
    	while(r>=l)
    	{
    		int mid=(l+r)/2;
    		if(a[mid].y<key)	ans=mid,l=mid+1;
    		else	r=mid-1;
    	}
    	return ans;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&a[i].x,&a[i].y);
    		a[i].val=a[i].y-a[i].x+1;
    	}
    	sort(a+1,a+1+n,com);
    	for(int i=1;i<=n;i++)
    	{
    		int j=find(1,i-1,a[i].x);
    		f[i]=max(f[i-1],f[j]+a[i].val);
    	}
    	cout<<f[n];
    	return 0;
    }
    

    (还可以直接枚举每个y坐标,那么转移就是从区间右端点刚好是枚举值的点转移过来)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=3000010;
    vector<int>bb[maxn];
    int maxx,f[maxn];
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		int l,r;
    		scanf("%d%d",&l,&r);
    		bb[r].push_back(l);
    		maxx=max(maxx,r);
    	}
    	for(int i=1;i<=maxx;i++)
    	{
    		f[i]=f[i-1];//不选当前区间 
    		for(int j=0;j<bb[i].size();j++)
    		{
    			int b=bb[i][j];
    			f[i]=max(f[i],f[b-1]+i-b+1);
    		}
    	}
    	cout<<f[maxx];
    }
    
  • 相关阅读:
    MD5 SHA1 CRC32
    tf 常用函数 28原则
    matplotlib 28原则
    markdown 基本语法
    tf 数据读取
    django 自定义身份认证
    代理部署
    社区发现算法问题&&NetworkX&&Gephi
    机器学习中的数学——拉格朗日乘子法
    过拟合(Overfitting)和正规化(Regularization)
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12876503.html
Copyright © 2011-2022 走看看