POJ 2686(状压DP
题目:
大意是有一个人从某个城市要到另一个城市(点数<=30)
然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票。
花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间。
问最后这个人花费的最短时间是多少
第一次做状压感觉那一长串for显示了这是个多么暴力的算法呢。。。1A了倒是挺顺的
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<utility> #include<vector> #include<cstring> #include<cmath> #define INF 0x3fffffff #define pb push_back #define pn(x) cerr<<x<<endl using namespace std; typedef long long ll; const int maxv=100005; int n,m,p,a,b; int t[10]; int G[35][35]; double dp[35][1<<9];////记录顶点和用掉的票的集合 int main(){ ////freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(cin>>n>>m>>p>>a>>b){ memset(G,0,sizeof G); if(!(n||m||p||a||b)) break; for(int i=0;i<n;i++) cin>>t[i]; for(int i=0;i<p;i++){ int v1,v2,w; scanf("%d%d%d",&v1,&v2,&w); G[v1][v2]=G[v2][v1]=w; } for(int i=0;i<35;i++) for(int j=0;j<1<<9;j++) dp[i][j]=1e10; dp[a][0]=0; for(int used=0;used<1<<n;used++) for(int i=1;i<=m;i++) for(int j=0;j<n;j++) if(used&1<<j) for(int k=1;k<=m;k++) if(G[i][k]) dp[k][used]=min(dp[k][used],dp[i][used&~(1<<j)]+G[i][k]/(double)t[j]); double ans=1e11; for(int i=0;i<1<<n;i++) ans=min(ans,dp[b][i]); if(ans>1e9) cout<<"Impossible"<<endl; else cout<<ans<<endl; } return 0; }