zoukankan      html  css  js  c++  java
  • Luogu P3620 [APIO/CTSC 2007]数据备份|反悔贪心

    例题链接

    题意:有(n)座大楼,要从中选出(k)对互异的大楼(即每座大楼仅可属于一组)接电话线。求电话线最短距离

    思路:

    显然的,我们应该选择相邻的大楼连电话线,否则不会最优。

    由题意可知,选择了一个间隔后,相邻两个间隔将不能选择,这种限制的解法是反悔贪心的一种

    下文中的点可能指点集,请读者自行理解

    该解法的具体思路是
    1.将点权排序
    2.当我们选择一个点(a)后,将选择(a)后受限制而不能选择的点集({B})的权值-点(a)的权值(相当于合成为一点替代了(a),下文称之为(c))加入考虑范围,点(a)以及点集({B})退出考虑范围。

    而当(c)被取出,这证明我们放弃了(a)而选择了({B}),而因为点(a)的权值被该操作抵消了,权值和也变为了选({B})而不选(a),是正确的。当然,选择({B})后需重复操作2。从上述操作可知,点(或点集)选择后会导致相邻的点的状态可能改变。用链表维护相邻状态即可解决。

    需要注意的是,边界问题会导致某些状态不合法,进而使程序WA,所以应根据实际情况,将边界设为无穷大/小

    例题代码如下,代码中,“考虑范围”将用手写的小根堆维护。在代码实现中(i=1)情况不合法,(i=n+1)情况不合法,因此将(1)(n+1)的点权设置为较大数组以保证无法取到。

    #include<bits/stdc++.h>
    using namespace std;
    long long g,h[100100],ha[100100],p[100100],l[100100],r[100100];
    bool vis[100100];int n,k,a[100100],s,sum;
    void add(long long x,int xx)
    {
    	h[++g]=x;ha[g]=xx;
    	int fa=g/2,so=g;
    	while (h[fa]>h[so]&&fa)
    	{
    		swap(h[fa],h[so]);
    		swap(ha[fa],ha[so]);
    		so=fa;fa=fa/2;
    	}
    }
    int del()
    {
    	int ans=ha[1];s=h[1];
    	h[1]=h[g];ha[1]=ha[g];g--;
    	int fa=1,so=2;
    	if (h[so]>h[so+1]&&so+1<=g) so++;
    	while (h[fa]>h[so]&&so<=g)
    	{
    		swap(h[fa],h[so]);
    		swap(ha[fa],ha[so]);		
    		fa=so;so*=2;
    		if (h[so]>h[so+1]&&so+1<=g) so++;
    	}
    	return ans;
    }//手写堆
    int main()
    {
        cin>>n>>k;
        p[1]=p[n+1]=1e17;
        for (int i=1;i<=n;i++)
        {
        	cin>>a[i];
        	if (i!=1) 
    		{
    			p[i]=a[i]-a[i-1];
    			add(p[i],i);
    		}			
    		l[i]=i-1;r[i]=i+1;
        }
        for (int i=1;i<=k;i++)
        {
        	int q=del();
    		{
    			 if (vis[q]) {i--;continue;}
    			 sum+=s;
    			 vis[l[q]]=vis[r[q]]=true; //维护“延迟删除”
    			 p[q]=-p[q]+p[l[q]]+p[r[q]];
    			 add(p[q],q);//将上文的“点c”加入考虑范围
    			 l[q]=l[l[q]];r[q]=r[r[q]];
    			 l[r[q]]=q;r[l[q]]=q;//维护相邻位置
    		}
        }
        cout<<sum<<endl;
    	return 0;
    }
    

    同类题目:

    SP1553 BACKUP - Backup Files

    Luogu P1484 种树

    Luogu P1792 种树

  • 相关阅读:
    C# 项目提交过程中感受
    C# 工作中遇到的几个问题
    C# Enum Name String Description之间的相互转换
    Win 10下安装 Redis
    Entity Framework 学习系列(3)
    Entity Framework 学习系列(2)
    Entity Framework 学习系列(1)
    解决 win10 家庭版环境下 MySQL 的ODBC驱动下载及安装
    Echarts 学习系列(3)-Echarts动态数据交互
    Echarts 学习系列(2)-常见的静态ECharts图
  • 原文地址:https://www.cnblogs.com/fmj123/p/13939244.html
Copyright © 2011-2022 走看看