状态压缩dp入门--------TSP问题


TSP问题
给你n个城市和城市之间的通路的长度,请你找出一条经过所有城市一次且仅经过一次的路线,使得这条路线的长度最短。


问题分析,如果要设计一个状态的话,显然状态与已经走过的城市和你当前所在的城市有关,现在,按照一定的顺序给每个城市一个编号,如果已经走过的城市记为1,没走过的城市记为0,那么已经走过的城市的状态就可以压缩成一个数。所以,该题目的状态表示为:

i=5~000101表示点1和点3已被访问
dp[i][j]表示分析在当前的状态i下,路径都为已经访问过的城市,找一条最短路径到达的j的总距离
       相应的状态转移方程为dp[ i ][ j]=min( dp[ i ^ (1<

 i ^ (1<状态压缩dp入门--------TSP问题_第1张图片


TSP基础问题

memset(dp, inf, sizeof(dp));  
for (int i = 1; i <= n; i++)  
    dp[1<<(i - 1)][i] = 0;  
int ans = inf;  
for (int i = 0; i < (1<

hdu 3001

   After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.
Input There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File. Output Output the minimum fee that he should pay,or -1 if he can't find such a route. Sample Input
2 1
1 2 100
3 2
1 2 40
2 3 50
3 3
1 2 3
1 3 4
2 3 10
Sample Output
100
90
7 
题意:n个点m条边,求某个点出发所有城市都要到达,每个城市最多可以被访问2次,求最短距离

题解:使用3进制存储状态:0,1,2次访问

#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int w[20][20];
int dp[60000][20];
int bit[12] = {0,1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049};//0001,0010,0100,1000...对应的十进制数
int num[60000][20];//某个十进制数的3进制形式存入num
int n,m;
void make_bit()
{
    for(int i=1;i<59050;i++)
    {
        int n=i,j=1;
        while(n)
        {
            num[i][j++]=n%3;
            n=n/3;
        }
    }
}
int main()
{
    make_bit();
    while(cin>>n>>m)
    {
        memset(w,-1,sizeof(w));
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            cin>>a>>b>>c;
            if(w[a][b]==-1)
                w[a][b]=w[b][a]=c;
            else
                w[a][b]=w[b][a]=min(w[a][b],c);//防止出现重边
        }
        memset(dp,inf,sizeof(dp));
        for(int i=1;i<=n;i++)
            dp[bit[i]][i]=0;
        int ans=inf;
        for(int i=1;i




你可能感兴趣的:(动态规划)