zoukankan      html  css  js  c++  java
  • # 交换茸角 状态DP 思路清奇

    交换茸角 状态DP 思路清奇


    问题:
    动物园里有 $n $头麋鹿。每头麋鹿有两支茸角,每支茸角有一个重量。

    然而,一旦某头麋鹿上两支茸角的重量之差过大,这头麋鹿就会失去平衡摔倒。为了不然这种悲剧发生,动物园院长决定交换某些茸角,使得任意一头麋鹿的两角重量差不超过$ c$。
    然而,交换两支茸角十分麻烦,不仅因为茸角需要多个人来搬运,而且会给麋鹿造成痛苦。因此,你需要计算出最少交换次数,使得任意一头麋鹿的两角重量差不超过 (c)

    注意,交换两支茸角只能在两头麋鹿之间进行。因为交换同一头麋鹿的两支角是没有意义的。


    解:
    这道题思路真的不容易想到
    首先我想了半天 发现普通的状态无法推导

    然后我看了一眼题解 还是 感觉 思路真的难想到

    首先 我们应该先抛开 最小交换的条件 而去考虑不满足条件的因素
    我们贪心一下
    显然就是 排完序后 两两 之差 (>c)
    满足条件的情况 就是 两两之差 (<=c)

    然后我们考虑 状态压缩 首先我们先设 f[i]为 集合i 里面都满足条件的最小步数

    • 对于集合里面不满足条件的 显然是 inf
    • 对于集合里面满足条件的 是0
    • 而 满足条件但是原来不满足的 设为集合个数 sum-1

    (f[i]=min(f[j]+)(f[i)^(j]));

    考虑区间合并

    这道题另一个思路清奇的地方
    为什么这么做是对的,所以 我们可以对于那些需要全部交换的,答案就是sum-1
    而对那些有的不需要交换的 可以通过子集递推

    code:

    //
    #include<bits/stdc++.h>
    using namespace std;
    #define maxnn 1000000
    int n;
    int a1[maxnn],a2[maxnn];
    int tmp[maxnn];
    int tot=0;
    int f[maxnn];
    int all=0;
    #define inf 10000000
    int c;
    int main()
    {
    	cin>>n>>c;
    	all=(1<<n)-1;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a1[i]);
    		scanf("%d",&a2[i]);
    	}
    	for(int s=0;s<=all;s++)
    	{
    		tot=0;
    		int ty=0;
    		int fla1=1;
    		for(int i=1;i<=n;i++)
    		{
    			if(s&(1<<i-1))
    			{
    				ty++;
    				tmp[++tot]=a1[i];
    				tmp[++tot]=a2[i];
    				if(abs(a1[i]-a2[i])>c) fla1=0;
    			}
    		}
    		sort(tmp+1,tmp+1+tot);
    		int fla=1;
    		for(int i=tot;i>=2;i-=2)
    		{
    			if(tmp[i]-tmp[i-1]>c)
    			{
    				fla=0;
    			}
    		}
    		if(fla==0) f[s]=inf;
    		else 
    		if(fla1==1) f[s]=0;
    		else
    		f[s]=ty-1;
    	}
    	for(int s=0;s<=all;s++)
    	{
    		for(int i=s;i;i=(i-1)&s)
    		{
    			int k=s^i;
    			f[s]=min(f[s],f[i]+f[k]);
    		}
    	}
    	if(f[all]!=inf) cout<<f[all];
    	else cout<<-1;
    	
    	
    	
    }
    
    
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    统计代码行数
    梯度下降算法
    multiplot 安装与配置
    ros 源码安装
    cmake 指定gcc/g++版本
    python 科学计算基础库安装
    协方差矩阵的含义
    pysvn 相关
    void 0与undefined
    BEM规范
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11454743.html
Copyright © 2011-2022 走看看