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

状态:每一列的每个数[ 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. 又议android中的manifest清单文件

    写过java程序的人,都知道了配置文件时java实现各种各样的框架的一大利器,manifest清单文件对android的作用自然不言而喻,然而他里面究竟定义了些什么,并且他是如何加载到程序中的. 他里 ...

  2. windows10(64位)Anaconda3+Python3.6搭建Tensorflow(cpu版本)及keras

    转自:windows10(64位)Anaconda3+Python3.6搭建Tensorflow(cpu版本)及keras 1.本来电脑安装的是anaconda3 5.3.1,但安装的python版本 ...

  3. SQL-查询排名

    select row_number() over(order by amount) as rank,* from dbo.t_group

  4. tcp协议的端口状态

    Listening Syn_sent syn_rcvd established close_wait time_wait --------- 对方主动关闭(对方调用close()), 我方的状态变为 ...

  5. (转)[unity3d]easytouch的使用

    对于移动平台上的RPG类的游戏,我们常用虚拟摇杆来控制人物角色的行走和一些行为,相信我们对它并不陌生,之前尝试了EasyTouch2.5,发现并没有最新版的3.1好用,2.5版本的对于自适应没有做的很 ...

  6. 在Foreda8上安装libaio-0.3.105-2.i386.rpm

    libaio-0.3.105-2.i386.rpm是安装MySql必须的包,可以从这里下载:http://pan.baidu.com/share/link?shareid=2348086735& ...

  7. (LeetCode 153)Find Minimum in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...

  8. Linux命令行和Shell高效率使用方法

    Ctrl+R快速搜索history Ctrl+P显示上一条命令 快速执行一条history命令:!!/!-number ======================================== ...

  9. php之快速入门学习-10(数组)

    PHP 数组 数组能够在单个变量中存储多个值: <?php $cars=array("Volvo","BMW","Toyota"); ...

  10. Linux安装 微信开发者工具(deepin linux ubt)

    一.环境:: deepin linux15.4.1 二.安装过程: 2.1 安装wine sudo apt-get install wine 2.2 安装nwjs-sdk 2.2.1 下载linux版 ...