一道C语言棋盘最优路径的题目,求教

作者&投稿:仝律 (若有异议请与网页底部的电邮联系)
如图 这道题除了棋盘法解 还能用别的方法么 觉得棋盘法有点麻烦~

可以不用棋盘法的。

由于基因Y或T纯合时致死,所以亲代的基因型都是:TtYy,
则子代的基因型可以这样考虑,
Tt与Tt的后代是Tt:tt=2:1(因为TT的已经致死了),
Yy与Yy的后代是Yy:yy=2:1,(因为YY的已经致死了),

将两种性状的分离比相乘,也就是将2Tt、1tt与2Yy、1yy进行组合,
结果就是4TtYy、2Ttyy、2ttYy、1ttyy,
所以后代的表现型及其比例是4:2:2:1。

路径通常是字符串,而C语言中没有String类型,通常是用字符指针来表示,例如
char *path="d:\\image.jpg";
希望对你有帮助。

这题还是有点意思的。
正如diordna所说,因为涉及到全局最优,
大小又是1000x1000,感觉广搜有点困难,所以打算试试DP。。

思路如下,不知道对不对。。


Part.1
设map[i][j]保存棋盘格子的价值 (i = 0..n-1, j = 0..m-1)
设f[i][j][k]记录棋盘(i, j)位置的最大价值和 (i = 0..n-1, j = 0..m-1, k = 0,1,2)
k表示这个位置是怎么来的:
k = 0: 左→右
k = 1: 上→下
k = 2: 下→上
首先初始化 f[i][j][k] = -inf
然后根据题意有:f[0][0][k] = map[0][0], k = 0,1,2


Part.2
又因为不能向左走,实际上就是说第j = 0列的格子只能向下走
所以可以先把f[i][0][1]算出来
f[i][0][1] = max(k=0,1){f[i-1][0][k]} + map[0][j] = f[i-1][0][1] + map[i][0], i = 1..n-1


Part.3
然后考虑任意一个非第0列的格子(i, j), i = 0..n-1, j = 1..m-1
便于思考特殊化一下,假设考虑第j = 1列(当然其它列也一样),
任意一个格子有3种到达方式,分别对应k = 0, 1, 2
但此时我们只知道每个格子的左边格子里的f值
那么我们先计算k=0时刻各格子的f值 (左→右)
f[i][j][0] = max(k=0,1,2){f[i][j-1][k]} + map[i][j], i = 0..n-1, j = 1


Part.4
这样一来各个格子从左边来到后的总价值f就得到了
接下来处理从上到下和从下到上的情况
由于从某个格子开始一旦选择从上到下或从下到上走后就无法回头了
不妨从上到下开始:
f[i][j][1] = max(k=0,1){f[i-1][j][k]} + map[i][j], i = 1..n-1, j = 1
然后从下到上:
f[i][j][2] = max(k=0,2){f[i+1][j][k]} + map[i][j], i = n-2..0, j = 1


Part.5
这样一来每个格子对应的3种走法的价值最大值就能得到了
如此回到Part.3循环列j = 1..m-1


最后只要取max(k=0,1){f[n-1][m-1][k]} 即可得到最优路径价值和

 

试着写了一下,不知道能不能过。。

注意由于开了1000x1000的long数组,所以VC调试的时候注意把堆栈开大一点

#include <iostream>
using namespace std;
#define MAXN 1000
#define INF 0x7fffffff
long map[MAXN][MAXN];
long f[MAXN][MAXN][3];
long getmax(long a, long b){ return (a > b) ? a : b;}
void init()
{
 for(int i = 0; i < MAXN; i++)
 {
  for(int j = 0; j < MAXN; j++)
  {
   map[i][j] = -INF;
   f[i][j][0] = -INF;
   f[i][j][1] = -INF;
   f[i][j][2] = -INF;
  }
 }
}
int main()
{
 // Part.1
 int n, m;
 cin >> n >> m;
 init();
 for(int i=0; i<n; i++)
 {
  for(int j=0; j<m; j++)
  {
   cin >> map[i][j];
  }
 }
 f[0][0][0] = f[0][0][1] = f[0][0][2] = map[0][0];
 // Part.2
 for(int i=1; i<n; i++)
 {
  f[i][0][1] = f[i-1][0][1] + map[i][0];
 }
 for(int j=1; j<m; j++)
 {
  // Part.3
  for(int i=0; i<n; i++)
  {
   long max = getmax(getmax(f[i][j-1][0], f[i][j-1][1]), f[i][j-1][2]);
   if(max == -INF) continue;
   f[i][j][0] = max + map[i][j];
  }
  // Part.4
  for(int i=1; i<n; i++)
  {
   long max = getmax(f[i-1][j][0], f[i-1][j][1]);
   if(max == -INF) continue;
   f[i][j][1] = max + map[i][j];
  }
  for(int i=n-2; i>=0; i--)
  {
   long max = getmax(f[i+1][j][0], f[i+1][j][2]);
   if(max == -INF) continue;
   f[i][j][2] = max + map[i][j];
  }
 }
 
 cout << getmax(f[n-1][m-1][0], f[n-1][m-1][1]) << endl;
 
 return 0;
}


这是经典算法中的最短路径算法的变形。关于这道题,有几个点需要注意。1,不能左走。2,权值要最小。3,不能重复走。
那么上来先把我们的迷宫画出来:new一个或者mloc一个二维数组。然后再给数组内容初始化一些权值。
new一个struct存储我当前的位置(x,y)。每次右走就是Y+1,上走就是X-1,下走就是x+1。
new一个二维数组,记录isvisited,是否访问过。初始化为都是0,访问过为1。

下面就是解题的思路:
这是个贪心的问题,你每一步的选择不能保证你全局贪心,但是你能保证你局部贪心。(这句话可能不好理解,但是你先暂时这么看,这个题解的差不多你就能理解。)所以,咱不能每一步都3个方向选个最小的。
这时候我们想到了广度优先搜索。广度优先搜索需要用到栈这种数据结构,希望你也接触过。具体的广度优先搜索我就不详述了,网上很多。

关于这个问题,还有个递归的解决方法,但是可能比较难理解。如果你实在看不懂bfs我再给你讲笨办法把。

到c语言论坛里比较好问


为什么很多人觉得C语言只要学会了指针基本上差不多掌握这门语言?
其实很重要的一个障碍就是指针,如果对于指针了解清楚,再去切入数据结构的学习就会显得轻松许多,指针作为C语言里面最重要的语法一点不为过,但是认为掌握了指针C语言就会显得非常肤浅。任何一种编程语言的背后都是大量的编程模式以及编程的套路,这些只有在真正的项目实战中才能掌握,而且对于一种编程语言越...

零基础学习C语言
零基础学习C语言:本人在网上找了很久关于如何学习C语言,本人也是新手不知该如何开始学习,无意中发现这本书慢慢的我找到了学习的头绪!推荐给大家学习目录 前言 第一篇 C语言基础 第1章 踏上征程前的思想动员 1.1 为什么选择C语言 1.2 如何学好C语言 1.3 语言概述 1.3.1 什么是语言 1.3.2 什么是机器语言 1.3....

如何学习C语言
还有一个“C语言学习系统”软件,不过感觉只是一个题库系统,如果你觉得题做的不够,不妨也可以试试。 2:葵花宝典学习计算机语言最好的方法是什么?答曰:读程序。没错,读程序是学习C语言入门最快,也是最好的方法。如同我,现在学习新的J#,C#等其他语言,不再是抱着书本逐行啃,而是学习它们的例程。当然,对于没有学...

求c语言 算法 求大神的代码
说白了这道题是数学题,首先要知道位数越多,值越大,那么也就是说在两个加号之间的位数越小,值就越小。假设串的长度为size 那么1:如果M+1被串的长度整除,这个最简单,直接把这个串平分分成M+1分,在中间加入+号,也就是在size\/(M+1)+(size\/(M+1)+1)*i, i=0,1,2...处插入加号 ...

从零开始学习C语言编程
找一些C语言编程相关的书来看。 这篇指南涵盖了C语言中最基础的部分,但对于完整的C语言只是体系来说这只是皮毛。如果能有一本好的参考书你在学习C语言的道路上能省去许多麻烦加入一些社区。不论是在线上还是线下,都有一些很棒的致力于学习和发展优秀编程语言的社区。如果能找到一些志同道合的C语言程序员,并和...

深入学习C语言的具体步骤
C语言是可以写很多核心和高级的东西,而不只是小东西,但是从你代码来看,居然用到了 goto,我不是说你那些程序用到GOTO有什么不好,而是一定要避免用GOTO,goto是错误之源,如果你有什么内容非要用到goto才能写到,说明你的编码技巧还有不少提高空间。你的学习顺序应该是:C:做一个超级马里奥出来,并...

C语言高手!!帮忙写个最短路径程序!!!
(3) 为来访客人提供图中任意景点的问路查询,即查询任意两个景点之间的一条最短的简单路径。【测试数据】由读者根据实际情况指定。二、概要设计 本次实验中运用到的数据类型有:图,顶点,边结点 typedef struct edgenode { int adjvex; \/\/临接点序号 int length; \/\/道路长度 char name[...

广度优先搜索C语言算法
Type: 广度优先搜索求最短步数 Method :从目标结点向回搜索,初始结点有多个 \\***\/ include <stdio.h> include <string.h> define DATASIZE 201 define QUEUESIZE 65536 typedef struct { int x,y;}CPOINT;int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa);int direction[][...

C语言的发展及其特点
3.C语言功能齐全。具有各种各样的数据类型,并引入了指针概念,可使程序效率更高。而且计算功能、逻辑判断功能也比较强大,可以实现决策目的的游戏。 c语言 4. C语言适用范围大。适合于多种操作系统,如Windows、DOS、UNIX等等;也适用于多种机型。 C语言对编写需要硬件进行操作的场合,明显优于其它解...

C语言怎么学
循环结构可以减少源程序重复书写的工作量,用来描述重复执行某段算法的问题,这是程序设计中最能发挥计算机特长的程序结构,C语言中提供四种循环,即goto循环、while循环、do –while循环和for循环。四种循环可以用来处理同一问题,一般情况下它们可以互相代替换,但一般不提倡用goto循环,因为强制改变程序的顺序经常会给程序的...

顺义区17318915953: 一道C语言棋盘最优路径的题目,求教 -
姬滢吉舒: 这题还是有点意思的. 正如diordna所说,因为涉及到全局最优, 大小又是1000x1000,感觉广搜有点困难,所以打算试试DP.. 思路如下,不知道对不对..Part.1 设map[i][j]保存棋盘格子的价值 (i = 0..n-1, j = 0..m-1) 设f[i][j][k]记录棋盘(i...

顺义区17318915953: C语言题目:要求输出国际象棋棋盘. -
姬滢吉舒: 你不用去关心219,219本身是int型,而%C得意思是要输出219的char型;我估计你是循环里面不太明白,%2指得是余2,是0就是写上黑方格,就是所谓得219的char型,esle相反是1就写上白方格,所以他打印出来的是" ",还有什么不明白的吗

顺义区17318915953: 一道简单的c语言题目求解 -
姬滢吉舒: #include <stdio.h> int main() { char c[5]; printf("输入4位数\n"); scanf("%s",c); for(int i=0;i<4;i++) printf("%c ",c[i]); scanf("%s",c); return 0; }

顺义区17318915953: 一道C语言题目!求大神帮忙啊! -
姬滢吉舒: 前面没看 不过下面这里不对for (i = 0; i < y; i++) if (*(x + i) = 1) ////这里应该是 == 不是= 判断相等使用== printf("这个剩下的人的原号码是%d号...

顺义区17318915953: 求解一道C语言题目! -
姬滢吉舒: #include #define BUF_SIZE 1024 void main() { int i, c; char buf[BUF_SIZE]; if(!fgets(buf, sizeof(buf), stdin)) return; i = 0; for(i = 0; buf[i] && (buf[i] != '@'); i++){ c = buf[i]; if((c >= 'A') && (cif((c >= 'a') && (cif(c == 'z') c = 'a'; else c += 1; buf[i] = c; } } if(buf...

顺义区17318915953: 请教一道C语言的题目 -
姬滢吉舒: #include <stdio.h>#define N 10 //长度是10 void Rmove(int *num,int n)//向右移 { int temp; temp = num[n-1]; --n; while(n>0) { num[n] = num[n-1]; --n; } num[0] = temp; } void Lmove(int *num,int n)//向左移 { int temp; int i=0; temp = num[0]; while(i<n-1) { ...

顺义区17318915953: 一道c语言题目 -
姬滢吉舒: 1:scanf("%c%d %c%d",&qi1,&qi2,&mo1,&mo2);在执行此条语句时,你的读入指针处于上一行的回车符,即你读入的qi1是'\n'.修改方法:scanf("%d\n",&n);指针后移一位. 2:强制类型转换不是你写的那种q=int(qi1);修改为:q = ...

顺义区17318915953: 请教一道C语言题目
姬滢吉舒: 假设在VC6里头生成了两个文件.一个aa.cpp, 另一个a.cpp. 那让aa.cpp里面想要调用的函数. 假设我在时面放了这两句: 然后我在a.cpp 就可以通过这句来调用aa.cpp的内容,再把里面的内容打印出来: 在调用文件,是要文件在同一目录.查看是否在同一文件夹下可以在这里看:

顺义区17318915953: 一道C语言题目,不会请教高手 -
姬滢吉舒: 当然是先排序再写入!提供一种方法:#include<stdio.h>#include<string.h>#include<stdlib.h> void main() { char str[240]; FILE *fp1; FILE *fp2; FILE *fp3; char str1[120],str2[120]; int i,j; char temp; if((fp1=fopen("A.TXT","r"))==NULL) { printf("...

顺义区17318915953: 求教一道C语言题 -
姬滢吉舒: #include"stdio.h" #define N 50 int count(int a,int b) {int c=a+b;return c%100; }int main() {int n,arr[N][2];printf("Input:\n");scanf("%d",&n);for(int i=0;i<n;i++)scanf("%d %d",&arr[i][0],&arr[i][1]);printf("Onput:\n");for(i=0;i<n;i++)printf("%d\n",count(arr[i][0],arr[i][1]));return 0;}

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网