您的位置:首页 > 其它

poj 3311 Hie with the Pie(状态压缩DP)

2014-10-03 11:21 302 查看
【题意】就是有0出发,到达所有的点后又回到0的走过的最少距离。
【状态】dp[i][state]表示到达i位置,状态为state时,走过的最少距离。
【转移】dp[i][state] = min(dp[i][state] ,dp[j][state ^ 1 <<(i-1)] + dis[j][i])。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define inf 0x7fffffff
int state[2000];
int dis[20][20];
int dp[20][2000];
int min(int a,int b)
{
return a > b ? b : a;
}
int main()
{
int n,i,j,k,l,ans,B;
while(scanf("%d",&n) && n)
{
for(i = 0;i <= n;i ++)
for(j = 0;j <= n;j ++)
cin >> dis[i][j];
for(i = 0;i <= n;i ++)
for(j = 0;j <= n;j ++)
for(k = 0;k <= n;k ++)
dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);
for(B = 0;B < 1 << n;B ++)
{
for(j = 1;j <= n;j ++)
if(B &(1 << (j - 1))) {
if(B == 1 << (j - 1))
dp[j][B] = dis[0][j];//本行state只包含j,认为是直接dis.
else
{
dp[j][B] = inf;
for(i = 1;i <= n;i ++)
if(B & 1 << (i - 1) && i != j)
dp[j][B] = min(dp[i][B ^ (1<< (j-1))] + dis[i][j],dp[j][B]);//如果不是只包含j,那么一定是又已经存在的
//那一个i状态转移过来的
}
}
}//对于每一行的情况,,可以对所有的state来判断。
ans = dp[1][B-1] + dis[1][0];
for(i = 2;i <= n;i ++)
ans = min(ans,dp[i][B-1] + dis[i][0]);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: