100道动态规划——1 UVA 1347 Tour 算法导论书后习题 双调巡游

来源:互联网 发布:中国国际地位知乎 编辑:程序博客网 时间:2024/05/22 13:48

                 这道题目实际上是算法导论动态规划那一章的一个书后习题,那个习题是说TSP是一个NP难问题,但是加上一个限制的话就可以利用动态规划把这个问题在多项式内解出来,也就是这道题目了。

                 限制了旅行的方式,让这个人向左一直走到底,然后一直向右走,这就不是随便的走了。

                这是紫书上的一个练习题,在当初没有看紫书的时候,直接对算法导论想了许久没有想出来,但是看了紫书之后感觉紫书的思路挺好的,自己以前从来没有这么想过。

                也做了一些DP的题目了,现在回想起来,还真的按照最优子结构来的,除了那些递推的题目。找到可以定义最优子结构的恰当的状态,然后开始递推或者刷表。

                不过能不能选取恰当的状态还是要看经验了,不过我总认为这里面应该存在着什么方法。

                这里采用的是刷表法,题目没有给出数据范围,dp的2000范围随便猜的。。。。

#include<cstdio>#include<vector>#include<cfloat>#include<cstring>#include<algorithm>#include<cmath>using namespace std;typedef pair<int,int> pa;pa p;int n;vector<pa> v;double dp[2010][2010],ans=DBL_MAX,te;inline double dis(const pa& a,const pa& b){return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));}int main(){    while(scanf("%d",&n)!=EOF){        for(int i=1;i<=n;++i)            scanf("%d%d",&p.first,&p.second),v.push_back(p);        dp[1][0]=dis(v[1],v[0]);        for(int i=1;i<n-2;++i)        for(int j=0;j<i;++j){            if(dp[i+1][j]<1E-6)                dp[i+1][j]=dp[i][j]+dis(v[i],v[i+1]);            else                dp[i+1][j]=min(dp[i+1][j],dp[i][j]+dis(v[i+1],v[i]));            if(dp[i+1][i]<1E-6)                dp[i+1][i]=dp[i][j]+dis(v[i+1],v[j]);            else                dp[i+1][i]=min(dp[i+1][i],dp[i][j]+dis(v[i+1],v[j]));        }        te=dis(v[n-1],v[n-2]);        for(int i=0;i<n-2;++i)            ans=min(ans,dp[n-2][i]+te+dis(v[i],v[n-1]));        printf("%.2lf\n",ans);        ans=DBL_MAX;        memset(dp,0,sizeof dp);        v.clear();    }    return 0;}


0 0
原创粉丝点击