(3311)POJ-状态压缩

来源:互联网 发布:淘宝网如何注销 编辑:程序博客网 时间:2024/05/24 06:12
#include<iostream>#include<cstdio>#include<string.h>#include<string>#include<stack>#include<set>#include<algorithm>#include<cmath>#include<vector>#include<map>#define ll __int64#define lll unsigned long long#define MAX 1000009#define eps 1e-8#define INF 0xfffffffusing namespace std;/*题意:给你n个点,和每个点之间的距离,问你从0,0点遍历所有点,每个点可以多次遍历的情况下,费用最小。想法:首先来个floyd,求个最短路,因为n(1<=n<=10),所以直接全排列就可以,枚举经过路径的状态,当然起始的时候是0,结束的时候也是0.      既然说到状态,我们就再来一发状态转移DP。。。。状态转移方程; dp[status][i] 表示i点到status状态下的最短距离dp[status][i] = min(dp[status][i],dp[status'][j] + op[j][i]);*/int n;int op[109][109];int dp[1<<11][50];int a[1009];int main(){    while(~scanf("%d",&n)&&n)    {        for(int i = 0; i<=n; i++)        {            for(int j = 0; j<=n; j++)            {                scanf("%d",&op[i][j]);            }        }        for(int k = 0; k<=n; k++)        {            for(int i = 0; i<=n; i++)            {                for(int j = 0; j<=n; j++)                {                    op[i][j] = min(op[i][j],op[i][k]+op[k][j]);                }            }        }        memset(dp,0,sizeof(dp));        for(int s = 0;s<(1<<n);s++)        {            for(int i = 1;i<=n;i++)            {                if(s&(1<<(i-1)))//状态S中包含第i个点                {                    if(s==(1<<(i-1)))
//状态S中只包含第i个点
                    dp[s][i] = op[0][i];
                    else
                    {
                        dp[s][i] = INF;
                        for(int j = 1;j<=n;j++)
                        {
                            if(s&(1<<(j-1))&&j!=i)//状态s含第j点并且j!=i
                            {
                                dp[s][i] = min(dp[s][i],dp[s&(~(1<<(i-1)))][j] + op[j][i]);
                            }
                        }
                    }
                }
            }
        }
        int _ans = MAX;
        for(int i = 1;i<=n;i++)
        {
            _ans = min(_ans,dp[(1<<n)-1][i] + op[i][0]);
        }
        cout<<_ans<<endl;
    }


    return 0;
}
#include<iostream>#include<cstdio>#include<string.h>#include<string>#include<stack>#include<set>#include<algorithm>#include<cmath>#include<vector>#include<map>#define ll __int64#define lll unsigned long long#define MAX 1000009#define eps 1e-8#define INF 0xfffffffusing namespace std;int n;int op[109][109];int a[1009];int main(){    while(~scanf("%d",&n)&&n)    {        for(int i = 0;i<=n;i++)        {            for(int j = 0;j<=n;j++)            {                scanf("%d",&op[i][j]);            }        }        for(int k = 0;k<=n;k++)        {            for(int i = 0;i<=n;i++)            {                for(int j = 0;j<=n;j++)                {                    op[i][j] = min(op[i][j],op[i][k]+op[k][j]);                }            }        }        for(int i = 0;i<n;i++) a[i] = i+1;        int _min = MAX;        do        {           int sum = 0;           for(int i = 0;i<n-1;i++)           {               sum +=op[a[i]][a[i+1]];           }           sum+=op[0][a[0]];           sum+=op[a[n-1]][0];           _min = min(_min,sum);        }while(next_permutation(a,a+n));        cout<<_min<<endl;    }    return 0;}
                                             
0 0