原题: HDU 3362 http://acm.hdu.edu.cn/showproblem.php?pid=3362

开始准备贪心搞,结果发现太难了,一直都没做出来。后来才知道要用状压DP。

题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的,可见题目中的图形sample。

由于n很小,而且固定点的顺序没有限制,所以需要用状态压缩DP。

注意:
1.当一个没固定的点和两个固定了的点连接后,该点就被(间接)固定了(三角形的稳定性质)
2.被固定的点还可以用来固定别的点

因此,对于当前需要固定的点,在已经是固定状态的点中选出两个距离当前点最小的,这就保证了局部最优,从起始状态开始转移,最后判断能否到达最终目标状态就可以了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Mod 1000000007
using namespace std;
#define N 100007 struct Point
{
double x,y;
int f;
}p[];
double dp[<<];
int unfix[];
double dis[];
int n; double Dis(int i,int j)
{
Point ka = p[i];
Point kb = p[j];
return (double)sqrt((ka.x-kb.x)*(ka.x-kb.x)+(ka.y-kb.y)*(ka.y-kb.y));
} double Fixit(int state,int tofix)
{
int i = ,j;
int tmp = state;
memset(dis,,sizeof(dis));
while(i < n)
{
if(tmp & ) //已固定点
{
unfix[i] = ;
dis[i] = Dis(tofix,i);
}
else
unfix[i] = ;
i++;
tmp >>= ;
}
double mini_1 = Mod;
int tag = -;
for(i=;i<n;i++) //选第一个点
{
if(!unfix[i]) //fixed
{
if(dis[i] < mini_1)
{
mini_1 = dis[i];
tag = i;
}
}
}
double mini_2 = Mod;
for(i=;i<n;i++) //选第二个点
{
if(i == tag) //选过
continue;
if(!unfix[i])
{
if(dis[i] < mini_2)
mini_2 = dis[i];
}
}
if(mini_1+mini_2 >= Mod)
return -;
return mini_1+mini_2;
} int main()
{
int i,j;
int Na;
while(scanf("%d",&n)!=EOF && n)
{
int S = ;
Na = (<<n)-;
for(i=;i<n;i++)
{
scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].f);
if(p[i].f)
S |= (<<i);
}
for(i=;i<=Na;i++)
dp[i] = Mod;
dp[S] = ;
for(i=S;i<Na;i++)
{
if(dp[i] == Mod)
continue;
for(j=;j<n;j++) //选一个unfix的点固定
{
if(i & (<<j)) //已fix,跳过
continue;
double delta = Fixit(i,j);
if(delta == -)
continue;
else //更新固定完这个点后的最少花费
dp[i|(<<j)] = min(dp[i|(<<j)],dp[i]+delta);
}
}
if(dp[Na] == Mod)
puts("No Solution");
else
printf("%.6lf\n",dp[Na]);
}
return ;
}

2014 Super Training #1 B Fix 状压DP的更多相关文章

  1. 2014 Super Training #7 C Diablo III --背包问题(DP)

    原题: ZOJ 3769 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3769 一个带有一些限制的背包问题. 假设在没有限 ...

  2. 2014 Super Training #10 D 花生的序列 --DP

    原题: FZU 2170 http://acm.fzu.edu.cn/problem.php?pid=2170 这题确实是当时没读懂题目,连样例都没想通,所以没做了,所以还是感觉这样散漫的做不好,有些 ...

  3. 2014 Super Training #8 C An Easy Game --DP

    原题:ZOJ 3791 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3791 题意:给定两个0-1序列s1, s2,操作t ...

  4. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

    题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...

  5. HDU 3362 Fix (状压DP)

    题意:题目给出n(n <= 18)个点的二维坐标,并说明某些点是被固定了的,其余则没固定,要求添加一些边,使得还没被固定的点变成固定的, 要求总长度最短. 析:由于这个 n 最大才是18,比较小 ...

  6. HDUOJ Clear All of Them I 状压DP

    Clear All of Them I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 122768/62768 K (Java/Oth ...

  7. ZOJ3802 Easy 2048 Again (状压DP)

    ZOJ Monthly, August 2014 E题 ZOJ月赛 2014年8月 E题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?proble ...

  8. 【状压dp】cf906C. Party

    需要稍加分析结论:还有一些小细节 Arseny likes to organize parties and invite people to it. However, not only friends ...

  9. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

随机推荐

  1. Hibernate的初步

    1.简介 在java开发领域,基于数据库应用的设计与实现一直都是面向关系的,Hibernate对象/关系映射ORM框架的出现为java面向对象开发提供了易于使用的数据持久化解决方案. ORM介绍: ( ...

  2. pbfunc外部函数扩展应用-直接在Datawindow中生成QR二维码,非图片方式

    利用pbfunc外部函数在Datawindow中直接生成QR二维码,非图片方式.需要注意以下面几点: Datawindow的DataObject的单位必须为像素(Pixels). Datawindow ...

  3. 转载 教你使用PS来制作unity3D随机地形

  4. Android 手机卫士18--流量统计

    //获取手机下载流量 //获取流量(R 手机(2G,3G,4G)下载流量) long mobileRxBytes = TrafficStats.getMobileRxBytes(); //获取手机的总 ...

  5. js中的浅拷贝和深拷贝

    说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...

  6. Thread.CurrentPrincipal & HttpContext.Current.User

    据说要这样写才稳妥 // This principal will flow throughout the request.VoyagerPrincipal principal = new Voyage ...

  7. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q66-Q69)

    Question 66You have a custom theme named MyTheme. The theme is defined in a file named MyTheme.thmx. ...

  8. [leetcode] Bitwise AND of Numbers Range

    Bitwise AND of Numbers Range Given a range [m, n] where 0 <= m <= n <= 2147483647, return t ...

  9. C++语言-01-简介

    简介 C++语言是C语言的超集,它扩充和完善了C语言:C++语言是一种静态类型的.编译时的.跨平台的.不规则的中级编程语言,综合了高级语言和低级语言的特点 C++支持的编程类型 面向对象编程 过程化编 ...

  10. 使用eclipse遇到问题:the-package-collides-with-a-type

    相似问题:http://stackoverflow.com/questions/12236909/the-package-collides-with-a-type