HDU 3362 Fix (状态压缩DP)
2015-05-29 19:13
363 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3362
题目大意:给出n(n<=18)个点的坐标,某些点固定了,某些点没固定,要求加一些边使得没固定的点变成固定,求最小花费。
思路:n比较小可用状压DP,从所给的起始状态开始DP,每个状态里面都枚举一个未固定的点然后通过找两个已经固定的点更新另一个状态,dp保存最优值即可。
Code:
题目大意:给出n(n<=18)个点的坐标,某些点固定了,某些点没固定,要求加一些边使得没固定的点变成固定,求最小花费。
思路:n比较小可用状压DP,从所给的起始状态开始DP,每个状态里面都枚举一个未固定的点然后通过找两个已经固定的点更新另一个状态,dp保存最优值即可。
Code:
/* W w w mm mm 222222222 7777777777777 */ /* W w w w m m m m 222 22 7777 */ /* w w w w m m m m 22 777 */ /* w w w w m m m m 22 77 */ /* w w w w m m m m 222 77 */ /* w w w w m m m m 222 77 */ /* w w w w m m m m 222 77 */ /* w w w w m m m m 222 77 */ /* w w w w m m m m 222 77 */ /* ww ww m mm m 222222222222222 77 */ //#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; int n; const int N=20; const int maxn=300005; double dist[20]; int st,en; struct Point { double x,y; int c; }a ; double dp[maxn]; void init() { for(int i=0;i<(1<<n);i++) { dp[i]=-1; } } void debug() { for(int i=st;i<(1<<n);i++) { printf("dp[%d]=%f\n",i,dp[i]); } } void debug_dist() { for(int i=1;i<=n;i++) { printf("dist[%d]=%f\n",i,dist[i]); } } double dis(int i,int j) { return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x) +(a[i].y-a[j].y)*(a[i].y-a[j].y)); } void solve() { st=0; for(int i=1;i<=n;i++) { if(a[i].c) { st+=1<<(i-1); } } dp[st]=0; //printf("st=%d\n",st); en=(1<<n)-1; for(int i=st;i<=en;i++) { if(dp[i]<0) { continue; } for(int j=1;j<=n;j++) { if(!(i&(1<<(j-1)))) { //printf("i=%d j=%d\n",i,j); int cnt=0; for(int p=1;p<=n;p++) { if((i&(1<<(p-1)))) { //printf("p=%d\n",p); dist[cnt++]=dis(j,p); //printf("%f\n",dis(j,p)); } } if(cnt<2)continue; //debug_dist(); sort(dist,dist+cnt); int S=i+(1<<(j-1)); if(dp[S]<0) { dp[S]=dp[i]+dist[0]+dist[1]; } else { dp[S]=min(dp[S],dp[i]+dist[0]+dist[1]); } //debug_dist(); } } } } int main() { #ifdef ONLINE_JUDGE #else freopen("test.in","r",stdin); #endif while(~scanf("%d",&n)) { if(!n)break; for(int i=1;i<=n;i++) { scanf("%lf%lf%d",&a[i].x,&a[i].y,&a[i].c); } init(); solve(); //debug(); if(dp[(1<<n)-1]<0) { printf("No Solution\n"); } else { printf("%.6f\n",dp[(1<<n)-1]); } } return 0; }
相关文章推荐
- linux快捷键
- OC基础语法学习2:面向对象中的特点
- 软件工程--第五次作业--(1、2、3、4(1))
- C语言输出菱形for循环
- thinkphp 退出登陆
- win git error init_cheap-VirtualAlloc pointer is null, Win32 error 487
- 设计模式之Proxy模式(笔记)
- 携程:网络故障由员工错误操作导致
- 一些开源项目整理
- Valid Phone Numbers
- WEBFORM--第一讲
- 请柬(invite)
- 【8. HA模块】云跳板机服务系统设计及实现
- 【项目实战】--Office文件上传
- jenkins gradle 编译遇到tomcat异常
- CentOS安装hadoop2.6.0
- 2-1
- 2-2
- 算法之神奇的位运算
- 基础篇--使用终端