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

状态:每一列的每个数[ 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. 科幻大片中那些牛X代码真相

    在<黑客帝国>中,救世主Neo的队友通过屏幕上"1"和"0"构成的数据流,就能看到鲜活的画面,这应该算是科幻大片中对代码最极致的表现了.其他科幻电影 ...

  2. VUE性能优化总结

    1.v-show,v-if 用哪个? 在我来看要分两个维度去思考问题: 第一个维度是权限问题,只要涉及到权限相关的展示无疑要用 v-if, 第二个维度在没有权限限制下根据用户点击的频次选择,频繁切换的 ...

  3. Android NFC近场通信03----读写MifareClassic卡

                                           Android NFC近场通信02----读写MifareClassic卡 一.MifareClassic卡 相关 一般来 ...

  4. HIVE部署安装(笔记)

    1.下载hive:wget http://mirrors.cnnic.cn/apache/hive/hive-0.12.0/hive-0.12.0.tar.gz2.解压hive安装文件 tar -zv ...

  5. 火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件

    1 CoorPreviews 不打开网页链接预览该网页的内容. 预览如图所示: 点击关闭旁边的钉子可以让该窗口保持开着并且浏览速度加快.这对于快速浏览图片时非常有用. 2 FoxTab 3D方式预览网 ...

  6. The connection to adb is down, and a severe error has occured. 错误

    错误:The connection to adb is down, and a severe error has occured. [2010-03-11 09:36:56 - HelloOPone] ...

  7. 页面可视化编辑ckeditor(web基础学习笔记十五)

    一.CKedit下载ckedit 下载地址:http://ckeditor.com/ 二.ckedit的引入 2.1.解压并将ckedit复制到项目中 2.2.在页面中引入 在页面头部加入 <s ...

  8. plsql 存储过程 测试

      plsql 存储过程 测试 CreationTime--2018年8月14日09点54分 Author:Marydon 1.找到要运行的存储过程-->选中-->右键-->测试 2 ...

  9. 对opencv MeanShift 融合矩形框的改进

    OPENCV 中的代码改进.当然要依据自己的实际情况来,OPENCV 中行人检測有两种矩形框的融合算法.这里仅仅对meanshift 方法做改进 假设有更好的方法.希望能够跟我讲下. 对于去除重合部分 ...

  10. url请求返回结果测试工具(CURL)

    官网:http://curl.haxx.se/download.html 具体用法用时百度 或  到时再补充