【结论】【状压DP】

26 篇文章 0 订阅
5 篇文章 0 订阅

1、
在n个节点的无向图中选n/2条边,使得点两两配对,并使得所选边权值最小

阶段:每一种已选点组成的集合
状态:s表示已选的点的集合,f[s]表示已选出的点连边后的最小权值。
决策:每条边选或不选
方程:f[sU{u,v}]=min f[s]+w(u,v)

代码:

for(int i=0;i<=s;i++) f[i]=inf;
    f[0]=0;
    for(int i=0;i<=s;i++)
    {
        for(u=0;(i>>u)&1;u++);
        //找最小的、没选出的点
        for(v=u+1;v<nn;v++)
        //枚举比u大的点
         if(!((i>>v)&1))//如果没选
         {
            t=i|(1<<u)|(1<<v);
            f[t]=min(f[t],f[i]+ma[g[u]][g[v]]);
         }
    }
ans=f[s];

EG:http://blog.csdn.net/y__xv/article/details/51997443

2、
找出简单有向图的哈密顿回路

状态:f[s][i],表示已走过的点的集合为s,最后停下的点为i时,走过边最短距离。
方程:f[s{v}][v]=min(f[s][u]+w(u,v))

for(int j,i=1;i<=s;i++)
     for(j=0;j<=n;j++) f[i][j]=1e9;
    f[1][0]=0;
    int u,v,t;
    for(int i=1;i<=s;i++)
     for(u=0;u<=n;u++)
      if((i>>u)&1)
       for(v=0;v<=n;v++)
        if(!((i>>v)&1))
        {
            t=i|(1<<v);
            f[t][v]=min(f[t][v],f[i][u]+a[u][v]);
        }
    int ans=1e9;
    for(int i=1;i<=n;i++)
    {
        ans=min(ans,f[s][i]+a[i][0]); 
    }

EG:http://blog.csdn.net/y__xv/article/details/51997772

3、
有n个物品,m个容器,每个容器只能装某一个特定的子集,不能多也不能少。每个容器有相应的费用,现在希望把全部物品都装进容器,且使用容器的总费用最少。(m可能非常非常大)

状态:f[s]表示已选物品的集合s所能取得的最小费用
方程:f[s]=min(f[s\t]+w[t])

枚举子集:

for(i=s&(s-1);i;i=s&(i-1))
    //从大到小枚举s的所有非空真子集 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值