zoukankan      html  css  js  c++  java
  • bzoj 2131: 免费的馅饼【dp+树状数组】

    简单粗暴的dp应该是把馅饼按时间排序然后设f[i]为i接到馅饼能获得的最大代价,转移是f[i]=max(f[j])+v[i],t[j]<=t[i],2t[i]-2t[j]>=abs(p[i]-p[j])
    后面这个条件就很麻烦,我们分情况讨论拆成两个,也就是当p[i]>p[j],满足2t[i]-p[i]>=2t[j]-p[j],和当p[i]<=p[j],满足2t[i]+p[i]>=2t[j]+p[j],然后注意到,因为t[j]<=t[i],所以满足2t[i]-p[i]>=2t[j]-p[j]则一定有p[i]>p[j],满足2t[i]+p[i]>=2t[j]+p[j]则一定有p[i]<=p[j]
    那么条件就变成了t[j]<=t[i]&&2t[i]-p[i]>=2t[j]-p[j]||2t[i]+p[i]>=2t[j]+p[j],再推一下,如果满足2t[i]-p[i]>=2t[j]-p[j],2t[i]+p[i]>=2t[j]+p[j],合起来就是t[j]<=t[i],然后条件就变成2t[i]-p[i]>=2t[j]-p[j]&&&2t[i]+p[i]>=2t[j]+p[j]
    然后一维排序,另一维树状数组优化dp即可

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<algorithm>
    using namespace std;
    const int N=200005;
    int n,m,f[N],g[N],has,t[N],ans;
    map<int,int>mp;
    struct qwe
    {
    	int t,p,v,w1,w2;
    }a[N];
    bool cmp(const qwe &a,const qwe &b)
    {
    	return a.w1<b.w1||(a.w1==b.w1&&a.w2<b.w2);
    }
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    void update(int x,int v)
    {
    	for(int i=x;i<=has;i+=(i&(-i)))
    		t[i]=max(t[i],v);
    }
    int ques(int x)
    {
    	int r=0;
    	for(int i=x;i>=1;i-=(i&(-i)))
    		r=max(r,t[i]);
    	return r;
    }
    int main()
    {
    	m=read(),n=read();
    	for(int i=1;i<=n;i++)
    		a[i].t=read()*2,a[i].p=read(),a[i].v=read(),a[i].w1=a[i].t-a[i].p,a[i].w2=g[i]=a[i].t+a[i].p;
    	sort(g+1,g+1+n);
    	for(int i=1;i<=n;i++)
    		if(i==1||g[i]!=g[i-1])
    			mp[g[i]]=++has;
    	sort(a+1,a+1+n,cmp);
    	for(int i=1;i<=n;i++)
    		a[i].w2=mp[a[i].w2];
    	for(int i=1;i<=n;i++)
    	{
    		f[i]=ques(a[i].w2)+a[i].v;
    		update(a[i].w2,f[i]);
    		ans=max(ans,f[i]);
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    tcp为什么要三次握手
    TCP/IP协议(一)网络基础知识
    拜占庭将军问题深入探讨
    Block Manager
    Standalone 集群部署
    Spark内存管理
    Checkpoint & cache & persist
    Python——在Python中如何使用Linux的epoll
    网络编程——C10K简述
    网络编程——The C10K Problem(C10K = connection 10 kilo 问题)。k 表示 kilo,即 1000
  • 原文地址:https://www.cnblogs.com/lokiii/p/9857584.html
Copyright © 2011-2022 走看看