第一次做动规题目,下面均为个人理解以及个人方法,状态转移方程以及状态的定义也是依据个人理解。请过路大神不吝赐教。

状态:每一列的每个数[ i ][ j ]都是一个状态;

然后定义状态[ i ][ j ]的指标函数d[ i ][ j ]为从[ i ][ j ]向右出发的能够得到的最小的整数和;

状态转移方程:d[ i ][ j ]=min(d[ i+1 ][ j+1 ][ i-1 ][ j+1 ][ i ][ j+1 ])+a[ i ][ j ];

当中a[ i ][ j ]为当前位置的数值;

然后有了这些就能够用自己熟悉的方式对问题求解了。

我所知道的合理求解过程有两种:记忆化搜索和递推。

我所知道的输出方法有两种:在求解过程中记录最优位置并在最后输出。全然在输出过程中寻求最佳位置并输出;

下面是自己写的两种输出不同的方法,其处理求解过程均为递推,我觉得对本题来讲记忆化搜索比較复杂,而递推又显而易见

1.

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long ll;
int m,n;
int a[50][1100];
int rd[50][1100];
ll d[50][1100]; ll min_ans(ll t1,ll t2 ,ll t3)
{
long long temp=min(t1,t2);
temp=min(temp,t3);
return temp;
}
int min_pos(ll ans,int y,int x1,int x2,int x3)
{
int pos=m+1;
if(ans==d[x1][y])
{
pos=min(pos,x1);
}
if(ans==d[x2][y])
{
pos=min(pos,x2);
}
if(ans==d[x3][y])
{
pos=min(pos,x3);
}
return pos;
}
void dp()
{
for(int i=n;i>=1;i--)
{
for(int j=1;j<=m;j++)
{
int temp1=j-1;
if(temp1==0) temp1=m;
int temp2=j+1;
if(temp2>m) temp2=1;
ll t1,t2,t3,ans;int pos;
t1=d[temp1][i+1];t2=d[j][i+1];t3=d[temp2][i+1];
d[j][i]=min_ans(t1,t2,t3)+a[j][i];
rd[j][i]=min_pos(d[j][i]-a[j][i],i+1,temp1,j,temp2);
}
}
}
void print_ans(int pp)
{
int cur=1;
printf("%d",pp);
while(cur!=n)
{
printf(" %d",rd[pp][cur]);
pp=rd[pp][cur];
cur++;
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(d,0,sizeof(d));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
dp();
long long min_ = -1;
for(int i=1;i<=m;i++)
{
if(min_==-1) min_=d[i][1];
else
min_=min(min_,d[i][1]);
}
int pp;
for(int i=1;i<=m;i++)
{
if(d[i][1]==min_)
{
pp=i;
break;
}
}
print_ans(pp);
printf("\n");
printf("%lld",d[pp][1]);
printf("\n");
}
return 0;
}

2.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; typedef long long ll;
int m,n;
int a[50][1100];
int rd[50][1100];
ll d[50][1100]; ll min_ans(ll t1,ll t2 ,ll t3)
{
long long temp=t1>t2? t2:t1;
return temp>t3?t3:temp;
} void dp()
{
for(int i=n; i>=1; i--)
{
for(int j=1; j<=m; j++)
{
int temp1=j-1;
if(temp1==0) temp1=m;
int temp2=j+1;
if(temp2>m) temp2=1;
ll t1,t2,t3,ans;
int pos;
t1=d[temp1][i+1];
t2=d[j][i+1];
t3=d[temp2][i+1];
d[j][i]=min_ans(t1,t2,t3)+a[j][i];
}
}
}
void print_ans(int pp,int cur)
{
printf("%d",pp);
cur++;
while(1&&cur<=n)
{
int i;
for(i=1; i<=m; i++)
{
if((d[i][cur]==d[pp][cur-1]-a[pp][cur-1]))
{
if(pp==1&&(i==m||i==pp||i==pp+1))
{
printf(" %d",i);
break;
}
else if(pp==m&&(i==1||i==pp||i==pp-1))
{
printf(" %d",i);
break;
}
else if(i>=pp-1&&i<=pp+1)
{
{
printf(" %d",i);
break;
}
}
else
continue;
}
}
pp=i;
cur++;
if(cur>n)
break;
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(d,0,sizeof(d));
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%d",&a[i][j]);
}
}
dp();
long long min_ = -1;
for(int i=1; i<=m; i++)
{
if(min_==-1) min_=d[i][1];
else
min_=min(min_,d[i][1]);
}
int pp;
for(int i=1; i<=m; i++)
{
if(d[i][1]==min_)
{
pp=i;
break;
}
}
print_ans(pp,1);
printf("\n");
printf("%I64d",d[pp][1]);
printf("\n");
}
return 0;
}

第一次做动规题目,花了好久才做好,由于期间出了一些小错误(如今看来依然是一些细节上的错误。与动规无关),并且由于对动规的不熟悉。心里对其也有一点点的恐惧。

可是认定这一道动规并不难,有时自己独立杰出的第一道动规题目。十分想要独立将其AC。然后一直找细节測数据。最终是找到了几处非常不应该犯的细节处理上的错误。这一点让我非常伤心。但最终的AC胜过千言万语。

之后选择还有一种方法,也是磕磕绊绊才写出AC代码orz...

这就算是开了动规吧,多思考多钻研,多学习别人的优秀思路

uva 116 - Unidirectional TSP (动态规划)的更多相关文章

  1. uva 116 Unidirectional TSP (DP)

    uva 116 Unidirectional TSP Background Problems that require minimum paths through some domain appear ...

  2. uva 116 Unidirectional TSP【号码塔+打印路径】

    主题: uva 116 Unidirectional TSP 意甲冠军:给定一个矩阵,当前格儿童值三个方向回格最小值和当前的和,就第一列的最小值并打印路径(同样则去字典序最小的). 分析:刚開始想错了 ...

  3. UVA 116 Unidirectional TSP(dp + 数塔问题)

     Unidirectional TSP  Background Problems that require minimum paths through some domain appear in ma ...

  4. UVA 116 Unidirectional TSP(DP最短路字典序)

    Description    Unidirectional TSP  Background Problems that require minimum paths through some domai ...

  5. uva 116 Unidirectional TSP(动态规划,多段图上的最短路)

    这道题目并不是很难理解,题目大意就是求从第一列到最后一列的一个字典序最小的最短路,要求不仅输出最短路长度,还要输出字典序最小的路径. 这道题可以利用动态规划求解.状态定义为: cost[i][j] = ...

  6. UVa - 116 - Unidirectional TSP

    Background Problems that require minimum paths through some domain appear in many different areas of ...

  7. UVA - 116 Unidirectional TSP 多段图的最短路 dp

    题意 略 分析 因为字典序最小,所以从后面的列递推,每次对上一列的三个方向的行排序就能确保,数字之和最小DP就完事了 代码 因为有个地方数组名next和里面本身的某个东西冲突了,所以编译错了,后来改成 ...

  8. UVA 116 Unidirectional TSP 经典dp题

    题意:找最短路,知道三种行走方式,给出图,求出一条从左边到右边的最短路,且字典序最小. 用dp记忆化搜索的思想来考虑是思路很清晰的,但是困难在如何求出字典序最小的路. 因为左边到右边的字典序最小就必须 ...

  9. UVa 116 Unidirectional TSP (DP)

    该题是<算法竞赛入门经典(第二版)>的一道例题,难度不算大.我先在没看题解的情况下自己做了一遍,虽然最终通过了,思路与书上的也一样.但比书上的代码复杂了很多,可见自己对问题的处理还是有所欠 ...

随机推荐

  1. PowerDesigner导入SQL脚本

    方法/步骤     打开PowerDesigner,鼠标单击File菜单:   选择:Reverse Enginer,然后在他的子菜单选择Database...;   选择好DBMS(数据库管理系统) ...

  2. 简单使用CSS3实现炫酷读者墙效果

    读者墙,在很多网站上都有,没有遇到过的,可以参考度娘:读者墙http://www.baidu.com/s?wd=%B6%C1%D5%DF%C7%BD 使用基础的Html和CSS写出雏形 需要一提的是头 ...

  3. Realm Swift

    Realm Swift 当前这个翻译,主要是方便我自己查阅api,有非常多地方写的比較晦涩或者没有翻译,敬请谅解 version 0.98.7 官方文档 參考文献 Realm支持类型 String,N ...

  4. 手机WiFi万能钥匙查看破解的password和手机查询命令收集

    手机须要网络利用WiFi万能钥匙破解了WIFI的password.手机就能够上网了,但假设想在电脑上使用手机破解的Wifi热点上网就须要password,此时须要知道手机破解的password,WiF ...

  5. 【K8S】K8S-网络模型、POD/RC/SVC YAML 语法官方文档

    K8S-网络模型.POD/RC/SVC YAML 语法官方文档 Kubernetes - Production-Grade Container Orchestration kubernetes/kub ...

  6. (转)NGUI类关系图

  7. 从头说catalan数及笔试面试里那些相关的问题 (转)

    作者:寒小阳 时间:2013年9月. 出处:http://blog.csdn.net/han_xiaoyang/article/details/11938973. 声明:版权所有,转载请注明出处,谢谢 ...

  8. M2Mqtt is a MQTT client available for all .Net platform

    Introduction M2Mqtt is a MQTT client available for all .Net platform (.Net Framework, .Net Compact F ...

  9. 如何使用FF的Firebug组件中的net工具查看页面元素加载消耗时间

    1.安装FF的Firebug组件:点击FF的Tools的Add-ons菜单,输入Firebug关键字,并选择合适的版本Install. 2.安装完毕后地址栏右边会出现一个小虫图标,右边还有一个下拉箭头 ...

  10. Android Environment.getExternalStorageDirectory() 获取的是内部存储还是外部存储?

    这几天在做Android应用的远程更新功能,将下载的更新包放在移动设备上指定的文件夹. 用的是  Environment.getExternalStorageDirectory() 这种方法.然后在获 ...