首页 > 其他 > 详细

# 交换茸角 状态DP 思路清奇

时间:2019-09-03 21:39:17      阅读:141      评论:0      收藏:0      [点我收藏+]

交换茸角 状态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;
    
    
    
}

# 交换茸角 状态DP 思路清奇

原文:https://www.cnblogs.com/OIEREDSION/p/11454743.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!