首页 > 代码库 > 8C-动态规划

8C-动态规划

给你若干个位置和一个起始位置,每次你可以由起始位置到任意一个非起始位置并返回起始位置或者由起始位置到非起始位置再到另一个非起始位置并返回起始位置,每次的代价为距离的平方,求最少代价经过每个位置一次(起始位置除外)

 

#include <iostream>#include <vector>#include <string>#include <algorithm>#include <sstream>#include <fstream>#include <cmath>#include <cstdlib>#include <cstdio>#include <cstring>#include <complex>using namespace std;typedef complex<int> point;typedef pair<int,int> pii;unsigned int dp[1<<24];point origin;int x,y;int n;point pts[30];int dist[30][30];int checkDist[30][30];int distancee(int i, int j) {    return norm(pts[i]-pts[j]);}int checkDistance(int i, int j) {    return dist[i][n]+dist[i][j]+dist[j][n];}void precompute() {    int i,j;    for(i=0;i<=n;++i) for(j=i;j<=n;++j) {        dist[i][j] = distancee(i,j);        dist[j][i] = dist[i][j];    }    for(i=0;i<n;++i) for(j=i;j<n;++j) {        checkDist[i][j] = checkDistance(i,j);        checkDist[j][i] = checkDist[i][j];    }}int f(unsigned int mask) {    if(dp[mask]!=-1)return dp[mask];    if(mask==(1<<n)-1) {        dp[mask] = 0;        return 0;    }    int i,j;    int ret = -1;    int tmp;    for(i=0;i<n;++i) if( !(mask & (1<<i)) ) {        tmp = f(mask | (1<<i));        tmp += 2*dist[n][i];        if(tmp<ret || ret==-1) {            ret = tmp;        }        unsigned int tmpMask = mask;        for(j=i+1;j<n;++j) if( !(mask & (1<<j)) ) {            tmpMask = mask;            tmpMask |= (1<<j);            tmpMask |= (1<<i);            tmp = f(tmpMask);            tmp += checkDist[i][j];            if(tmp<ret || ret==-1) {                ret = tmp;            }        }        break;    }    dp[mask] = ret;    return ret;}int main() {    cin>>x>>y;    origin = point(x,y);    cin>>n;    int i,j;    for(i=0;i<n;++i) {        cin>>x>>y;        pts[i] = point(x,y);    }    pts[n] = origin;    precompute();    memset(dp,-1,sizeof dp);    int ret = f(0);    cout<<ret<<endl;    ostringstream sout;    sout<<"0";    unsigned int mask = 0;    int tmp;    while(mask != (1<<n)-1) {        for(i=0;i<n;++i) if(!(mask & (1<<i))) {            tmp = dp[mask | (1<<i)];            tmp += 2*dist[i][n];            if(tmp==dp[mask]) {                sout<<" "<<i+1<<" 0";                mask = mask | (1<<i);            }            else {                unsigned int tmpMask;                for(j=i+1;j<n;++j) if(!(mask & (1<<j))) {                    tmpMask = mask;                    tmpMask |= (1<<i);                    tmpMask |= (1<<j);                    tmp = dp[tmpMask];                    tmp += checkDist[i][j];                    if(tmp==dp[mask]) {                        sout<<" "<<i+1<<" "<<j+1<<" 0";                        mask = tmpMask;                        break;                    }                }            }            break;        }    }    cout<<sout.str()<<endl;    return 0;}

 

8C-动态规划