您的位置:首页 > 其它

D - Hie with the Pie (状态dp)

2017-12-02 21:18 148 查看
分析转自:http://blog.csdn.net/tc_to_top/article/details/43894747

题目大意:一个人要送n份货,给出一个矩阵,表示任意两个点间的直接路径的时间,求从起点0送完这n份货(到达指定的n个地点)再回到起点0的最短时间

思路:

n不大,可以进行状态压缩,首先用Floyd处理一下任意两点的最短路,dp[i][j]表示在状态i的条件下到城市j的最短时间,显然如果i == (1 << (j - 1)),表示从只经过城市j,这时候dp[i][j] = dis[0][j],否则就是要经过别的城市到达j,这里枚举当前状态下经过的除了j的其他城市,注意一定是当前状态下,这里类似Floyd,最后dp[(1
<< n) - 1][i]表示经过了所有店到达i我们只要枚举dp[(1 << n) - 1][i] + dis[i][0]的最小值即可

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
const int inf=0x7fffffff;
int dp[1<<11][11],n;
int dis[15][15];

void Floyd() //求ij最短路
{
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}

int main()
{
ios::sync_with_stdio(false);
while(cin>>n)
{
if(n==0)break;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
cin>>dis[i][j];
Floyd();
for(int i=0;i<=(1<<n)-1;i++)
{
for(int j=1;j<=n;j++)
{
if(i==(1<<(j-1)))
dp[i][j]=dis[0][j];
else
{
dp[i][j]=inf;
for(int k =1;k<= n;k++)
if((k!=j)&&(i&(1<<(k-1)))) //取i的第k-1位 - 是否为0,不为0则为真,为0则假
dp[i][j]=min(dp[i][j],dp[i^(1<<(j - 1))][k]+dis[k][j]);
}
}
}
int ans=dp[(1<<n)-1][1]+dis[1][0];
for(int i = 2; i <= n; i++)
ans = min(ans, dp[(1 << n)-1][i] + dis[i][0]);
cout<<ans<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 算法 状态dp