题意:有平面上有n个物品,一个人没次最多带两个物品,问这个人从起点出发,把所有物品拿到起点最少走过平方距离。
解题思路:就是把所有情况用二进制表示,在此基础上进行dp。这题的dp部分很简单,就是在上个状态的基础上更新拿物品i的总值。
参考博客:http://blog.csdn.net/mrsiz/article/details/48174943
附ac代码(有详细注释):
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <string.h> 5 #include <cmath> 6 #include <iostream> 7 #include <algorithm> 8 #include <queue> 9 #include <stack> 10 #include <vector> 11 typedef long long ll; 12 using namespace std; 13 const int maxn = 111; 14 const int inf = 0x3f3f3f3f; 15 struct nod{ 16 int x; 17 int y; 18 }nu[maxn],bg; 19 int getd(nod a,nod b) 20 { 21 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 22 } 23 int dp[1<<24]; 24 int dis[maxn][maxn]; 25 int pre[1<<24]; 26 int main() { 27 ios::sync_with_stdio(false); 28 int n; 29 cin>>bg.x>>bg.y; 30 cin>>n; 31 int len=(1<<n)-1; 32 for(int i=0;i<n;++i) 33 { 34 cin>>nu[i].x>>nu[i].y; 35 } 36 nu[n].x=bg.x; 37 nu[n].y=bg.y; 38 for(int i=0;i<=n;++i) 39 { 40 for(int j=0;j<=n;++j) 41 { 42 dis[i][j]=getd(nu[i],nu[j]); 43 } 44 } 45 46 int maxx=1<<24; 47 for(int i=1;i<maxx;++i) dp[i]=inf; 48 for(int i=0;i<=len;++i) //从一个都没拿的状态开始向后遍历 49 { 50 if(dp[i]!=inf) 51 { 52 for(int j=0;j<n;++j) 53 { 54 if(!(i&(1<<j))) 55 { 56 int t=i|(1<<j);//i的基础上拿了j物品的状态 57 int l=dp[i]+dis[n][j]+dis[j][n]; 58 if(dp[t]>l) 59 { 60 dp[t]=l;//更新 61 pre[t]=i;//记录路径 62 } 63 for(int k=j+1;k<n;++k)//j的基础上拿了k物品的状态 64 { 65 if(!(t&(1<<k))) 66 { 67 int p=t|(1<<k); 68 int l=dp[i]+dis[n][j]+dis[j][k]+dis[k][n]; 69 if(dp[p]>l) 70 { 71 dp[p]=l; 72 pre[p]=i; 73 } 74 } 75 } 76 break; 77 } 78 } 79 } 80 81 } 82 83 cout<<dp[len]<<endl; 84 cout<<0; 85 while(len>0) 86 { 87 for(int i=0;i<n;++i) if((len^pre[len])&(1<<i)) cout<<" "<<i+1; 88 cout<<" "<<0; 89 len=pre[len]; 90 } 91 92 return 0; 93 }