POJ 3229:The Best Travel Design
Description Dou Nai is an excellent ACM programmer, and he felt so tired recently that he wants to release himself from the hard work. He plans a travel to Xin Jiang .With the influence of literature, he wishes to visit Tian Chi, Da Ban Town, Lou Lan mysterious town , Yi Li , and other sights that also have great attraction to him. But the summer vocation time is not long. He must come back before the end of the summer vocation. For visiting more sights and all the necessary sights, he should make a thorough plan. Unfortunately, he is too tired to move, so you must help him to make this plan. Here are some prerequisites: there are two ways of transportation, bus and train, and velocity of the bus is 120km/h and the train is 80km/h. Suppose the travel is started from Urumuqi (point 1), and the end of the travel route is Urumuqi too. You need to spend some time to visit the sights, but the time of each visit is not always equal. Suppose we spend 12 hours on traveling every day. Input There are several test cases. For each case, the first line is three integers N, M and K. N (1<=n<=15) is the number of sights, M(0<=M<=N) is total sights he must arrived (sight 1 is always must be arrived) and K is total traveling time (per day). The second line is M integers which sights he must visited. The third line is N integers, the ith integer means the time he will stay in the sight i (per hour). Then several lines follow. Each line is four integers x, y, len and kind, 1<=x, y<=n, 0<len<=1000, means there is a bidirectional path between sights x and y, the distance is len, kind=0 means x and y are connected by train, kind=1 is by bus. x=y=len=kind=0 means end of the path explanation. N=M=K=0 means end of the input. Output For each case, output maximum sights he will travel with all necessary sights visited or "No Solution" if he can't travel all the sights he like best in time. Sample Input 3 3 3 1 2 3 10 8 6 1 2 120 0 1 3 60 1 2 3 50 1 0 0 0 0 3 3 2 1 2 3 10 8 6 1 2 120 0 1 3 60 1 2 3 50 1 0 0 0 0 0 0 0 Sample Output 3 No Solution
新疆地图……突然有点想家。
题目大意:一个人在新疆旅游,有几个地方他必须去,剩下去的越多越好,有时间限制。他从乌市出发最后回到乌市,城市之间有火车或大巴,用的时间不一样。
芒果君:这道题处理起来有点麻烦,但不难理解,算是状压DP的入门。先用floyd求最短路,然后进行记忆化搜索(DP和记搜搭配很强的,之前那道IOI的树型DP就是),枚举+松弛,多看几遍就能懂了233333333
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define inf 1<<29 using namespace std; double mp[20][20],cost[20],dp[1<<16][20]; int n,m,k,ans,tar; void init() { ans=tar=0; for(int i=0;i<n;++i){ for(int j=0;j<n;++j) mp[i][j]=inf; mp[i][i]=0; } for(int i=0;i<(1<<n);++i) for(int j=0;j<n;++j) dp[i][j]=inf; } void floyd() { for(int k=0;k<n;++k) for(int i=0;i<n;++i) for(int j=0;j<n;++j) mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]); } int sta(int x) { int t=x,sum=0; while(t){ if(t&1) sum++; t>>=1; } return sum; } double dfs(int x,int y) { if(dp[x][y]!=inf) return dp[x][y]; double t=inf; for(int i=0;i<n;++i) if(x&(1<<i)&&i!=y) if(i||(x^(1<<y))==1) t=min(t,dfs(x^(1<<y),i)+mp[i][y]+cost[y]); if((tar&x)==tar&&(t+mp[y][0])<=k) ans=max(ans,sta(x)); return dp[x][y]=t; } int main() { int x,y,op,t; double len; while(scanf("%d%d%d",&n,&m,&k)!=EOF){ if(!n&&!m&&!k) break; init(); k*=12; for(int i=0;i<m;++i){ scanf("%d",&t); tar|=1<<(t-1); } for(int i=0;i<n;++i) scanf("%lf",&cost[i]); while(scanf("%d%d%lf%d",&x,&y,&len,&op)!=EOF){ if(!x&&!y&&!len&&!op) break; x--,y--; mp[x][y]=mp[y][x]=min(mp[x][y],len/(80.0+op*40.0)); } floyd(); dp[1][0]=cost[0]; for(int i=1;i<n;++i) dfs((1<<n)-1,i); if(ans>0) printf("%d\n",ans); else puts("No Solution"); } return 0; }