It is limited, at the problem is not the solution, a lot of understanding
Thank you for watching this konjac
topic:
Problem C: Poj3311 Hie with the Pie
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 58 Solved: 29
[Submit][Status][Web Board]
Description
you have a n + 1 (1 <= n <= 10) have a complete graph to the point, it is given in matrix form between any two different points distance. (Where the distance from i to j is not necessarily equal to the distance from j to i) want you to find leaves from 0:00, walked to the number n 1 point of at least once, and then return to spend the minimum number 0:00 distance
Input
Output
Sample Input
3
0 1 10 10
1 0 1 2
10 1 0 10
10 2 10 0
0
Sample Output
8
HINT
This problem is generally similar to the previous question : https://www.cnblogs.com/nlyzl/p/11307139.html
Must be read with from 0 ~ n, this problem requires a number from 0 point, so the initial f [1] [0] = 0; i.e. 0 0:00 clicked to the end number is 0;
i required from 1 ~ (1 << n + 1) -1;
j: n ~ 0 To reverse cycle, because the title does not say can not turn back, so we want n Backward ensure that currently go with the opposite of the values go all know, for DP min to take us.
J and k because we all start from zero, so no 1 << (j-1) and 1 << (k-1) when the left
Direct and 1 << j can be 1 << k;
Transfer: f [i] [j] = min (f [i] [j], min (f [i ^ 1 << j] [k], f [i] [k]) + dis [k] [j ]); // i.e., a state should start taking the current state min and then to add the distance, again transferred ( because they can turn back )
The last statistics we have + dis [i] [0]; // distance from any point to zero
code:
#include<bits/stdc++.h> using namespace std; int n; int dis[21][21]; int ans; int f[1<<20][21]; inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void write(int x){ char F[200]; int tmp=x>0?x:-x ; if(x<0)putchar('-') ; int cnt=0 ; while(tmp>0) { F[cnt++]=tmp%10+'0'; tmp/=10; } while(cnt>0)putchar(F[--cnt]) ; } int main() { while(scanf("%d",&n)&&n!=0) { ans=INT_MAX; for(int i=0;i<=n;i++) { for(int j=0;j<=n;j++) { dis[i][j]=read(); } } memset(f,0x3f,sizeof(f)); f[1][0]=0; for(int i=1;i<=(1<<n+1)-1;i++) { for(int j=n;j>=0;j--) { if(i&1<<j) { for(int k=0;k<=n;k++) { if(i&1<<k&&j!=k) { f[i][j]=min(f[i][j],min(f[i^1<<j][k],f[i][k])+dis[k][j]); } } } } } for(int i=0;i<=n;i++) ans=min(ans,f[(1<<n+1)-1][i]+dis[i][0]); write(ans); cout<<endl; } return 0; }