hdu3001(三进制状态压缩DP)
来源:互联网 发布:新易城数据 编辑:程序博客网 时间:2024/06/17 06:05
这题和TSP(旅行售货员问题)本质区别是每个地方可以访问两下,而TSP只能访问一次,一开始题目读错了,用搜索来做结果wa了
后来看了解题,这个问题要用状态压缩来解。
题意:访问n个点,并且每个点最多访问两次,求最小费用
这里因为n较小,所以可以用状态压缩,每个点最多访问两次,所以要用三进制的状态压缩
解题思路:dp[i][S]表示当前状态为S,在i点;状态转移方程:dp[i][s] = min(dp[j][s1]+dist[i][j]),其中S表示含有i的状态,s1是新状态,s->s1,加了i到j的一条边
代码如下(附注释)
#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<time.h>#include<math.h>#define N 15#define inf 0x7fffffff#define eps 1e-9#define pi acos(-1.0)#define P system("pause")using namespace std;int n;int fac[N]={1,3,9,27,81,243,729,2187,6561,19683,59049};//3的0次到9次 int dist[N][N],dp[N][60000],state[60000][N];//dist[]记录输入信息;//dp[i][S]代表状态为S,且处于i点的最小费用;state[S][i]状态为S的三进制形式的第i位++的数字是多少(0,1,2) void init(){ int i; memset(state,0,sizeof(state)); for(i = 0; i < fac[10]; i++)//计算状态S的三进制形式中每一位的数字,但记录的方向是反向的 { int k = 0, temp = i; while(temp) { state[i][k++] = temp % 3; temp /= 3; } }}int is_ok(int k)//判断不存在一位是0 { int ans = 0; while(k) { if(k%3 == 0) return 0; k /= 3; ans++; } return ans;}int main(){//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout); // for(int i = 0; i < 10 ; i++) // cout<<fac[i]<<" "; init(); int m; while(scanf("%d%d",&n,&m) != EOF) { int i,j,k; int x,y,z; memset(dist,-1,sizeof(dist)); while(m--)//数据输入 { scanf("%d%d%d",&x,&y,&z); x--; y--; if(dist[x][y] == -1 || dist[x][y] > z) dist[x][y] = dist[y][x] = z; } memset(dp,-1,sizeof(dp)); for(i = 0; i < n; i++) dp[i][fac[i]] = 0; for(i = 0; i < fac[n]; i++) for(j = 0; j < n; j++) //dp[j][i],在i状态中加入一个结点 if(state[i][j] != 0 && dp[j][i] != -1) for(k = 0; k < n; k++) { if(dist[j][k] != -1 && j != k && state[i][k] < 2) { int ans = i + fac[k]; if(dp[k][ans] == -1) dp[k][ans] = dp[j][i] + dist[j][k]; else dp[k][ans] = min(dp[k][ans],dp[j][i] + dist[j][k]); //cout<<"fds"<<endl; } } int res = inf; for(i = 1; i < fac[n]; i++) { int k = is_ok(i); for(j = 0; j < n; j++) if(k != -1 && k == n) if(dp[j][i] != -1 && dp[j][i] < res) res = dp[j][i]; } if(res == inf) printf("-1\n"); else printf("%d\n",res); } // P; return 0; }
0 0
- hdu3001(三进制状态压缩DP)
- hdu3001 三进制状态压缩+dp
- hdu3001 状态压缩dp+三进制
- hdu3001(三进制状态压缩dp)
- hdu3001 三进制 状态压缩dp
- hdu3001 Traveling (三进制状态压缩dp)
- hdu3001 Travelling(状态压缩dp,三进制)
- hdu3001 Travelling 三进制状态压缩dp
- hdu3001(状态压缩dp,三进制!)
- hdu3001(状态压缩dp)
- 三进制状态压缩DP(旅行商问题TSP)HDU3001
- hdu3001 Travelling 三进制状态压缩
- hdu3001(3进制状态压缩dp)
- HDU3001(状态压缩TSP)
- HDU3001-Travelling-状态压缩
- HDU3001——Travelling(状态压缩DP)
- 状态压缩DP总结【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】
- (状态压缩) Travelling (HDU3001)
- apache http server 启动失败
- HTTP的工作原理
- 如何创建你自己的Git服务器
- 15.UIMenuController
- Redis的AOF功能
- hdu3001(三进制状态压缩DP)
- 我的第一个PHP脚本!
- 技巧: 使用truss、strace或ltrace诊断软件的"疑难杂症"
- Volley的应用(通过Json与服务器交互)
- Eclipse设置快捷提示的方法
- 通过ccb(CocosBuilder)文件生成cocos2dx代码
- Android 常用控件自定义样式RadioButton、CheckBox、ProgressBar、
- Horspool‘s算法和Boyer-Moore算法
- cocos2d基础篇笔记五