poj 3311 Hie with the Pie 状压dp

//参考了挑战程序设计第二版的tsp,dp[S][v]表示在已经访问了集合S中的点情况下//从出发访问剩下的节点并回到0号起点的最少花费dp[V][0]都是0,//从0号节点回到0花费肯定是0,//dp[S][v] = min(dp[S|{u}][u]+d[v][u],dp[S][v]){u不在当前的集合中}//这样我们从[0,0]这个状态开始进行记忆化搜索,,就一定能得到我们想要的答案//对于递推的做法,目前还有一丝的疑惑//书上说对于集合S(i)包含于S(j),就有i<=j;//solve3()中dp[S][v]表示当前在v点,还需访问S中的城市各一次后回到0处的最小花费//初始的时候dp[0][i]=d[i][0],其他都为无穷大,状态转移方程为//dp[S][v] = min(dp[S][v],dp[S-{j}][j]+d[i][j])(j属于S)//最后dp[S][0]就是我们要求的答案//每种做法,各有千秋吧,仅以此题纪念自己开启TSP之旅~继续练吧#include <algorithm>#include <bitset>#include <cassert>#include <cctype>#include <cfloat>#include <climits>#include <cmath>#include <complex>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <deque>#include <functional>#include <iostream>#include <list>#include <map>#include <numeric>#include <queue>#include <set>#include <stack>#include <vector>#define ceil(a,b) (((a)+(b)-1)/(b))#define endl '\n'#define gcd __gcd#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))#define popCount __builtin_popcountlltypedef long long ll;using namespace std;const int MOD = 1000000007;const long double PI = acos(-1.L);template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; }template<class T> inline T lowBit(const T& x) { return x&-x; }template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; }template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; }const int maxn = 13;int d[maxn][maxn];int dp[1 << maxn][maxn];int n;const int inf = 0x3f3f3f3f;void init(){n++;for (int i=0;i<n;i++)for (int j=0;j<n;j++)scanf("%d",&d[i][j]);}int dfs(int S,int v){if (dp[S][v]>=0)return dp[S][v];if (S==(1<<n)-1&&v==0){return dp[S][v]=0;}int res = inf;for (int u=0;u<n;u++)if (!((S>>u)&1)){res = min(res,dfs(S|(1<<u),u)+d[v][u]);}return dp[S][v] = res;}void floyd(){for (int k=0;k<n;k++)for (int i=0;i<n;i++)for (int j=0;j<n;j++)if (d[i][j]>d[i][k]+d[k][j])d[i][j] = d[i][k]+d[k][j];}void TSP(){//for (int i=0;i<n;i++)dp[(1<<n)-1][0]=0;for (int S=(1<<n)-1;S>=0;S–)for (int i=0;i<n;i++)for(int u=0;u<n;u++)if (!((S>>u)&1)){dp[S][i] = min(dp[S][i],dp[S|(1<<u)][u]+d[i][u]);}}void solve(){memset(dp,-1,sizeof(dp));printf("%d\n",dfs(0,0));}void solve2(){memset(dp,inf,sizeof(dp));TSP();printf("%d\n",dp[0][0]);}void print(){for (int i=0;i<(1<<n);i++){for (int j=0;j<n;j++)printf("%d ",dp[i][j]);puts("");}}void solve3(){memset(dp,inf,sizeof(dp));for (int i=0;i<n;i++)dp[0][i] = d[i][0];for (int S=0;S<(1<<n);S++)for (int v=0;v<n;v++)for (int u=0;u<n;u++)if ((S>>u)&1)dp[S][v] = min(dp[S][v],dp[S^(1<<u)][u]+d[v][u]);//int res=inf;//print();//for (int i=0;i<n;i++)//res = min(res,dp[i][0]);printf("%d\n",dp[(1<<n)-1][0]);}int main() {//freopen("G:\\Code\\1.txt","r",stdin);while(scanf("%d",&n)!=EOF){if (!n)break;init();floyd();//solve();//solve2();solve3();}return 0;}

你并不一定会从此拥有更美好的人生,

poj 3311 Hie with the Pie 状压dp

相关文章:

你感兴趣的文章:

标签云: