状压DP D - Hie with the Pie
2016-08-15 09:53
239 查看
问题描述:
Description
The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be processed before he starts any deliveries. Needless to say, he would like to take the shortest route in delivering these goodies and returning to the pizzeria, even if it means passing the same location(s) or the pizzeria more than once on the way. He has commissioned you to write a program to help him.
Input
Input will consist of multiple test cases. The first line will contain a single integer n indicating the number of orders to deliver, where 1 ≤ n ≤ 10. After this will be n + 1 lines each containing n + 1 integers indicating the times to travel between the pizzeria (numbered 0) and the n locations (numbers 1 to n). The jth value on the ith line indicates the time to go directly from location i to location j without visiting any other locations along the way. Note that there may be quicker ways to go from i to j via other locations, due to different speed limits, traffic lights, etc. Also, the time values may not be symmetric, i.e., the time to go directly from location i to j may not be the same as the time to go directly from location j to i. An input value of n = 0 will terminate input.
Output
For each test case, you should output a single number indicating the minimum time to deliver all of the pizzas and return to the pizzeria.
Sample Input
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
Sample Output
8
大致题意:
这是一个送披萨的问题,一共N和城市,每个城市都是连通的,现将每个道路的花费都给你。送披萨的小哥从0出发,要经过所有的城市并且回到0.要求最短花费。
思路分析:
这是一个TSP问题。
首先用folyd算法,求出每个点之间的最小花费。
dp【i】【j】代表第i个状态下以第j个点为结尾的最小花费。
状态转移方程。
dp[i][j]=min(dp[i][j],dp[i-(1<<(j-1))][kk]+mapp[kk][j]);
通过状态压缩,枚举所有的状态,然后枚举该状态下的最后一个点,最后再枚举前一个点(也就是倒数第2个点)。
ac代码:
Description
The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be processed before he starts any deliveries. Needless to say, he would like to take the shortest route in delivering these goodies and returning to the pizzeria, even if it means passing the same location(s) or the pizzeria more than once on the way. He has commissioned you to write a program to help him.
Input
Input will consist of multiple test cases. The first line will contain a single integer n indicating the number of orders to deliver, where 1 ≤ n ≤ 10. After this will be n + 1 lines each containing n + 1 integers indicating the times to travel between the pizzeria (numbered 0) and the n locations (numbers 1 to n). The jth value on the ith line indicates the time to go directly from location i to location j without visiting any other locations along the way. Note that there may be quicker ways to go from i to j via other locations, due to different speed limits, traffic lights, etc. Also, the time values may not be symmetric, i.e., the time to go directly from location i to j may not be the same as the time to go directly from location j to i. An input value of n = 0 will terminate input.
Output
For each test case, you should output a single number indicating the minimum time to deliver all of the pizzas and return to the pizzeria.
Sample Input
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
Sample Output
8
大致题意:
这是一个送披萨的问题,一共N和城市,每个城市都是连通的,现将每个道路的花费都给你。送披萨的小哥从0出发,要经过所有的城市并且回到0.要求最短花费。
思路分析:
这是一个TSP问题。
首先用folyd算法,求出每个点之间的最小花费。
dp【i】【j】代表第i个状态下以第j个点为结尾的最小花费。
状态转移方程。
dp[i][j]=min(dp[i][j],dp[i-(1<<(j-1))][kk]+mapp[kk][j]);
通过状态压缩,枚举所有的状态,然后枚举该状态下的最后一个点,最后再枚举前一个点(也就是倒数第2个点)。
ac代码:
#include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<iostream> using namespace std; int mapp[15][15]; int dp[1<<10+5][11]; int n; void flody(){ for(int k=0;k<n+1;k++) for(int i=0;i<n+1;i++) for(int j=0;j<n+1;j++) { if(mapp[i][k]+mapp[k][j]<mapp[i][j]) mapp[i][j]=mapp[i][k]+mapp[k][j]; } } int main() { int i,j,x; while(scanf("%d",&n),n) { for(i=0;i<n+1;i++) { for(j=0;j<n+1;j++) { scanf("%d",&mapp[i][j]); } } flody(); int the_end=1<<n; for(i=0;i<the_end;i++) { for(j=1;j<=n;j++) { if(i==(1<<(j-1))) { dp[i][j]=mapp[0][j]; continue; } //赋值最大! int t=(1<<(j-1)); if(i&t) { dp[i][j]=1<<30; for(int kk=1;kk<=n;kk++) { if(kk!=j&&(i&(1<<(kk-1)))) { dp[i][j]=min(dp[i][j],dp[i-(1<<(j-1))][kk]+mapp[kk][j]); } } } } } int ans=1<<30; for(int i=1;i<n+1;i++) { ans=min(ans,dp[(1<<n)-1][i]+mapp[i][0]); } printf("%d\n",ans); } }
相关文章推荐
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- LFC1.0.0 版本发布
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- Android dpi,dip,dp的概念以及屏幕适配
- 计算字符串最后一个单词长度
- Android px、dp、sp之间相互转换
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- 矩阵的乘法操作
- android中像素单位dp、px、pt、sp的比较