POJ 3311 Hie with the Pie【狀壓DP+floyed】
阿新 • • 發佈:2018-12-12
題意: 將所有外賣送去所有對應地點再回到店鋪,求最短路。 分析:Floyed預處理任意兩點最小距離,然後二維狀壓(最後的結束位置要考慮,不然回到起點的距離沒辦法計算)。 . PS:這種題不難,注意開的維度,仔細檢查狀壓時的下標。 狀壓寫法:
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define met(s) memset(s, 0, sizeof(s)) #define rep(i, a, b) for(int i = a; i <= b; ++i) template <class T> inline void scan_d(T &ret) { char c; ret = 0; while ((c = getchar()) < '0' || c > '9'); while (c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'), c = getchar();}} typedef long long LL; typedef unsigned long long ull; typedef pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 1e8; const int MAXN = 15; int dp[MAXN][1 << 12]; int mp[MAXN][MAXN]; int n, m; inline void floyed() { for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { for(int k = 1; k <= n; ++k) { mp[j][k] = min(mp[j][k], mp[j][i] + mp[i][k]); } } } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while(scanf("%d", &n) && n) { n += 1; memset(dp, INF, sizeof(dp)); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { scanf("%d", &mp[i][j]); } } floyed(); dp[1][1] = 0; int ans = INF; //for(int i = 0; i < n; ++i) dp[1 << i] = mp[1][i + 1]; for(int i = 1; i < (1 << n); ++i) { if(!(i & 1)) continue; for(int j = 0; j < n; ++j) { if((1 << j) & i) continue; for(int k = 0; k < n; ++k) { if(!((1 << k) & i)) continue; dp[j + 1][(1 << j) + i] = min(dp[j + 1][(1 << j) + i], dp[k + 1][i] + mp[k + 1][j + 1]); if((1 << n) - 1 == i + (1 << j)) { ans = min(ans, dp[j + 1][(1 << n) - 1] + mp[j + 1][1]); // printf("## %d %d\n", mp[k + 1][1], k + 1); } } } } printf("%d\n", ans); } return 0; }
_
#include <cstdio> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define met(s) memset(s, 0, sizeof(s)) #define rep(i, a, b) for(int i = a; i <= b; ++i) template <class T> inline void scan_d(T &ret) { char c; ret = 0; while ((c = getchar()) < '0' || c > '9'); while (c >= '0' && c <= '9') { ret = ret * 10 + (c - '0'), c = getchar();}} typedef long long LL; typedef unsigned long long ull; typedef pair<int, int> pii; const int INF = 0x3f3f3f3f; const int mod = 1e8; const int MAXN = 15; int a[15]; int mp[MAXN][MAXN]; int n, m; inline void floyed() { for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { for(int k = 1; k <= n; ++k) { mp[j][k] = min(mp[j][k], mp[j][i] + mp[i][k]); } } } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while(scanf("%d", &n) && n) { n += 1; for(int i = 1; i <= n; ++i) { a[i] = i; for(int j = 1; j <= n; ++j) { scanf("%d", &mp[i][j]); } } floyed(); int ans = INF; do { int sum = mp[a[n]][1] + mp[1][a[1]]; for(int i = 1; i < n; ++i) { sum += mp[a[i]][a[i + 1]]; } ans = min(sum, ans) ; }while(next_permutation(a + 2, a + n + 1)); printf("%d\n", ans); } return 0; }