zoukankan      html  css  js  c++  java
  • luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝

    LINK:智破连环阵

    考试的时候 题意没理解清楚 题目是指一个炸弹爆炸时间结束后再放另一个炸弹 而放完一个炸弹紧接另一个炸弹。题目中存在然后二字.

    这样我们可以发现某个炸弹只会炸连续的一段。

    但是 由于点的坐标虽然只在第一象限 炸弹也在第一象限 不过简单的设出几个状态可以发现 是不可行的。

    状压也不行。考虑贪心但是还是要要考虑坐标以及序号的问题 所以很难贪出正确答案。

    无奈之下只能选择搜索了 一种比较简单的搜索方式还是搜出把序列分段。

    可以发现这样复杂度最坏是2^n的。

    求出分段之后我们还需要考虑匹配问题。

    容易发现是一个二分图的问题直接跑匈牙利即可。

    考虑加剪枝以优化。

    一个比较容易想到的剪枝:最优化剪枝 对于当前点x 我们可以预估一个最优答案d[x]表示x~n都可以被满足且此时炸弹随便选的最小炸弹数 这样这个最优化剪枝的效果更好且保证答案正确。

    一个可行性剪枝:搜出当前分段后 先判断一下最大匹配是否成功再继续搜下去。

    一个接替前驱答案的优化:不需要每次最大匹配重新跑 可以直接直接拿上一层的结果跑。

    注意枚举区间由大到小做 这样也可以加快。

    一些其他剪枝我没加:如精确判断区间的右断点的最大延伸。这个还需要判断一下交错路什么的我觉得比较复杂 复杂度也比较高 所以就没加。在数据随机的情况下上述剪枝已经很快了。

    const int MAXN=110;
    int ans,n,m,k,id;//炸弹m个 n个点 a[i][j]表示第i个炸弹是否可以炸到点j.
    int a[MAXN][MAXN],c[MAXN][MAXN],d[MAXN];//c[i][j]表示第i个炸弹从j点开始炸的最远点.
    struct wy{int x,y;}A[MAXN],B[MAXN];//d[i]表示i~n个点被炸在每个点被用多次时的最小值.
    inline int pd(int x,int y){return pf(B[x].x-A[y].x)+pf(B[x].y-A[y].y)<=pf(k);}
    int f[MAXN],w[MAXN][MAXN],vis[MAXN];
    inline void prepare()
    {
    	rep(1,m,i)fep(n,1,j)if(a[i][j])c[i][j]=max(j,c[i][j+1]);
    	fep(n,1,i){d[i]=INF;rep(1,m,j)if(a[j][i])d[i]=min(d[i],d[c[j][i]+1]+1);}
    }
    inline int dfs(int x)
    {
    	rep(1,m,i)
    	{
    		if(vis[i]!=id&&w[i][x])
    		{
    			vis[i]=id;
    			if(!f[i]||dfs(f[i]))
    			{
    				f[i]=x;
    				return 1;
    			}
    		}
    	}
    	return 0;
    }
    inline void dfs(int x,int v)
    {
    	if(v+d[x]>=ans)return;
    	if(x==n+1){ans=v;return;}
    	int g[MAXN];
    	rep(1,m,i)g[i]=f[i];
    	fep(n,x,i)
    	{
    		rep(1,m,j)if(c[j][x]>=i)w[j][v+1]=1;
    		++id;if(dfs(v+1))dfs(i+1,v+1);
    		rep(1,m,j)if(c[j][x]>=i)w[j][v+1]=0;
    		rep(1,m,j)f[j]=g[j];
    	}
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(m);get(k);
    	rep(1,n,i){int get(x);A[i]=(wy){x,read()};}
    	rep(1,m,i){int get(x);B[i]=(wy){x,read()};}
    	rep(1,m,i)rep(1,n,j)a[i][j]=pd(i,j);
    	prepare();ans=INF;dfs(1,0);put(ans);
    	return 0;
    }
    
  • 相关阅读:
    高效App运营必须get的七个推送技巧
    如何预测您的用户即将流失?
    HMS Core赋能移动金融,为行业注入增长新动力
    做好自定义预测,探寻产品增长动能
    Unity平台 | 快速集成华为AGC云数据库服务
    HMS Core Insights第一期直播回顾 – 深入浅出,创新技术与开发者共同推进行业发展!
    多种细分方式浏览销售数据,IAP助您有效洞察市场收益效果
    Unity | 快速集成华为AGC云存储服务
    awk命令
    反转字符串
  • 原文地址:https://www.cnblogs.com/chdy/p/12745497.html
Copyright © 2011-2022 走看看