取数字问题取数字问题取数字问题

Description

给定M*N的矩阵,其中的每个元素都是-10到10之间的整数。你的任务是从左上角(1,1)走到右下角(M,N),每一步只能向右或向下,并且不能走出矩阵的范围。你所经过的方格里面的数字都必须被选取,请找出一条最合适的道路,使得在路上被选取的数字之和是尽可能小的正整数。

Input

第一行两个整数M,N,(2<=M,N<=10),分别表示矩阵的行和列的数目。

接下来的M行,每行包括N个整数,就是矩阵中的每一行的N个元素。

Output

仅一行一个整数,表示所选道路上数字之和所能达到的最小的正整数。如果不能达到任何正整数就输出-1。

Sample Input

2 2

0 2

1 0

Sample Output

1

题目大意:

有一个n*m的矩阵,每个位置都有一个-10~10的分数(每走到一个位置,就会自动得到当前位置的分数),要从(1,1)走到(n,m),要使分数是正整数,并且最小,若结果都非正整数,输出-1

方法一方法一方法一

解题方法:

先枚举一个i(结果),然后从(n,m)dfs到(1,1),使当前值为上一个f(存结果)减去当前的a(本来的数值),当(1,1)为0时,就是可以从(n,m)到(1,1),否则枚举下一个a,因为有负数所以存的时候要加一个M(我写的是1001)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#define M 1001
using namespace std;
int ans,n,m,a[15][15],f[15][15][M*2];
void dfs(int x,int y,int d)//x,y为行列,d为当前数
{f[x][y][d+M]=1;if (f[1][1][M]) return;if ((x>1)&&(!f[x-1][y][d-a[x-1][y]+M])) dfs(x-1,y,d-a[x-1][y]);//往上,要先判断是否越界,是否走过同样的数,如果走了同样的数就会浪费时间if ((y>1)&&(!f[x][y-1][d-a[x][y-1]+M])) dfs(x,y-1,d-a[x][y-1]);//往左,要先判断是否越界,是否走过同样的数,如果走了同样的数就会浪费时间
}
int main()
{ans=-1;scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)scanf("%d",&a[i][j]);//输入for (int i=1;i<=n*m*10;i++)//枚举结果{dfs(n,m,i-a[n][m]);//最后一个要先减去它的a值if (f[1][1][M]) //如果有结果就记录,break{ans=i;break;}}printf("%d",ans);
}

方法二方法二方法二

用DP的方法,用一个数组f[i][j][k]来表示第i行第j列是否能得到数字k,但k是已经加了一个M(我写的是1001)的,所以在输出时要从M+1开始

动态转移方程:

{if(f[i−1][j][k])f[i][j][k+a[i][j]]=1if(f[i][j−1][k])f[i][j][k+a[i][j]]=1\left\{\begin{matrix}if(f[i-1][j][k]) & f[i][j][k+a[i][j]]=1\\ if (f[i][j-1][k]) & f[i][j][k+a[i][j]]=1\end{matrix}\right.{if(f[i−1][j][k])if(f[i][j−1][k])​f[i][j][k+a[i][j]]=1f[i][j][k+a[i][j]]=1​

解释:

第一行的为取上的数,第二行的为取上的数

程序解析待续…

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#define M 1001
using namespace std;
int a[15][15],f[15][15][M*2+5],n,m,t;
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)scanf("%d",&a[i][j]);f[1][1][a[1][1]+M]=1;//(1,1)的值初始化为自己的值t=a[1][1]+M;//存好,后面要用for (int i=2;i<=n;i++)//第一列下去f[i][1][t+a[i][1]]=1,t+=a[i][1];//t为前面的值,加上当前的值,再赋值1,表示有这个数;后面一句是为了方便后面求值t=a[1][1]+M;//再存,后面还要用for (int j=2;j<=m;j++)//第一行f[1][j][t+a[1][j]]=1,t+=a[1][j];//同上for (int i=2;i<=n;i++)//行for (int j=2;j<=m;j++)//列for (int k=1;k<=M*2;k++)//上一个的数字{if (f[i-1][j][k]) f[i][j][k+a[i][j]]=1;//动态转移方程if (f[i][j-1][k]) f[i][j][k+a[i][j]]=1;//动态转移方程}int k=M+1;//因0~M-1是负数,M是0(提前加过了),所以从M+1开始while ((!f[n][m][k])&&(k<=M*2)) k++;//求最小,第二个判定是为了不出界if (k<=M*2) printf("%d",k-M);//如果大于M*2就说明无解else printf("-1");
}

方法三方法三方法三

直接相加,用一个三位数组f,f[i][j][0]表示第i行第j列有多少个数字,之后的f[i][j][k]表示他的数字

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a[11][11],n,m,ans,f[11][11][50000];
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)scanf("%d",&a[i][j]);f[1][1][0]=1;//初始化f[1][1][1]=a[1][1];//初始化for (int i=2;i<=n;i++)f[i][1][1]=f[i-1][1][1]+a[i][1],f[i][1][0]=1;//第一列for (int i=2;i<=m;i++)f[1][i][1]=f[1][i-1][1]+a[1][i],f[1][i][0]=1;//第一行for (int i=2;i<=n;i++)for (int j=2;j<=m;j++){f[i][j][0]=f[i-1][j][0]+f[i][j-1][0];//数字个数为上面数字个数加左边数字个数for (int k=1;k<=f[i-1][j][0];k++)f[i][j][k]=f[i-1][j][k]+a[i][j];//直接加for (int k=1;k<=f[i][j-1][0];k++)f[i][j][k+f[i-1][j][0]]=f[i][j-1][k]+a[i][j];//不能覆盖,要再加上f[i-1][j][0]}ans=2147483647;//因为要求最小,所以要赋一个大的值for (int i=1;i<=f[n][m][0];i++)if (f[n][m][i]>0)//排除负数和0ans=min(ans,f[n][m][i]);if (ans==2147483647) printf("-1");//如果没有改变,输出-1else printf("%d",ans);
}

【动态规划】【递归】取数字问题 (ssl 1644)相关推荐

  1. lintcode:递归打印数字

    题目 用递归打印数字 用递归的方法找到从1到最大的N位整数. 样例 给出 N = 1, 返回[1,2,3,4,5,6,7,8,9]. 给出 N = 2, 返回[1,2,3,4,5,6,7,8,9,10 ...

  2. python递归查找_Python程序使用递归查找数字的幂

    python递归查找 Given the base x and the power y and we have to find the x to the power y using recursion ...

  3. Burpsuite如何抓取使用了SSL或TLS传输的 IOS App流量

    之前一篇文章介绍了Burpsuite如何抓取使用了SSL或TLS传输的Android App流量,那么IOS中APP如何抓取HTTPS流量呢, 套路基本上与android相同,唯一不同的是将证书导入i ...

  4. pyspider抓取数字货币价格bitcoin

    上一篇文章讲了pyspider的安装(ubuntu18) 第一步,找数据源,发现数据源url的pattern 试试抓取数字货币价格, 数据源:https://coinmarketcap.com/zh/ ...

  5. Java动态规划走金字塔_【动态规划基础】数字金字塔

    1258:[例9.2]数字金字塔 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 9635     通过数: 5467 [题目描述] 观察下面的数字金字塔.写一个程 ...

  6. php 提取数字,php如何实现只取数字的功能

    php只取数字的实现方法:1.使用"preg_match"函数从字符串中提取数字出来:2.使用PHP内置的"in_array"方法将字符串中出现的数字都提取出来 ...

  7. python取数字前n位

    python取数字前n位 思路::如果我们要取一个位数很多的数字前n位(int型),可以将其转换为字符串类型后操作. #创建一个较大的数(阶乘) def jie(n):s=1for i in rang ...

  8. c语言程序中要用到阶乘,C程序使用递归求数字的阶乘

    C程序使用递归求数字的阶乘 在此示例中,您将学习查找用户使用递归输入的非负整数的阶乘. 要理解此示例,您应该了解以下C语言编程主题: 正数n的阶乘由下式给出: 示例factorial of n (n! ...

  9. VBA中关于WORD的基本应用 比如批量改页眉页脚,从文件名取数字作为页眉等等。

    VBA中关于WORD的基本应用 比如批量改页眉页脚,从文件名取数字作为页眉等等. 以下是代码,直接在Word的VBA编辑器里粘贴上去就OK了. Sub 批量转PDF() Dim i As Varian ...

最新文章

  1. iview构建基本html页面,使用vue-cli创造基于vue.js的iview工程
  2. SQL语言之DML语言学习(一) 数据插入与修改操作语言
  3. mysql正则提取字符串_mysql字符串查找截取与正则表达式的联合应用
  4. oracle取两条sql查询结果的差集,并集,交集
  5. Android——发送和接收广播
  6. html中select标签刷新后不回到默认值而是保持之前选择值
  7. 本特利3500_本特利技术控的自我修养之 轴位移探头安装
  8. 数据3分钟丨Databricks与Snowflake开撕;阿里云多款自研数据库支撑首个“100%云上双11”...
  9. 数据结构之图的存储结构二及其实现
  10. git的创建分支与合并分支(5)
  11. helloworld代码_12 种主流编程语言输出“Hello World”
  12. 【MySQL】Mcafee审计插件
  13. Blender 快捷键总结,一些子问题
  14. PDF解密工具—Cisdem PDF Password Remover
  15. 项目不同阶段的风险特征
  16. java连连看代码_Java版连连看
  17. 微信小程序中转义字符的处理
  18. 解决进不去BIOS或U盘启动,windows10如何关闭快速启动
  19. design contains shelved or modified (but not repoured) polygons. the result....继续铺铜还是报警,解决方案如下:
  20. 关于AS5 SSH支持key认证的完全解决方案

热门文章

  1. sql不等于0怎么表示_数组真的只能从0开始吗?python表示不同意
  2. java pc计数器_java虚拟机-程序计数器PC Register
  3. 7-4 N皇后 (28 分)(思路+详解)
  4. Java当中 IO(File) 操作 之 递归打印子孙级目录和文件名称
  5. [XML-Jsoup]Jsoup_对象的使用(Jsoup工具类,Document,Elements,Element,Node)
  6. [C++STL]C++实现vector容器
  7. 《C++ Primer》第一章的 Sales_item.h头文件源码
  8. 写出TREE-PREDECESSOR的伪代码(算法导论第三版12.2-3)
  9. SpringBoot项目新手——问题疑惑及解决笔记
  10. 最大公约数,最小公倍数,质因式分解