滚动数组(细节)(坑点)
2021-04-25 19:27
标签:依次 不能 递推 cpp 输入 using printf stdin next 滚动数组中本次0/1用完后,对后面结果无贡献了,一定要记得清零,否则会不断累积(一共就两个数0/1,循环多了肯定都快填满了) 你是否听说过这个游戏?游戏者在一张特殊的表格中按照规则跳动,使得跳到的数字经过加号和减号的连接,尽可能的逼近零。表格通常是如图 1.1所示的形状,大小由中间一行的方格数 N 决定(图 1.1 就是一个 N=4的例子)。 输入文件的第一行是 \(N(N,接下来 \(2?N?1\) 行给出了表格中每行的每个方格中的数字,第 \(i+1\) 行的第 \(j\) 个数字对应于表格中第 \(i\) 行的第 \(j\) 个数字。文件中第二行的数字表示的是表格顶端的方格中的数字。文件中所有的数字都是整数,同一行相邻的两个数字间用空格符隔开。 输出文件只有一行,是你所求出的最接近零的计算结果的绝对值。 4 0 表格中的所有数字大于等于?50,小于等于50。 滚动数组(细节)(坑点) 标签:依次 不能 递推 cpp 输入 using printf stdin next 原文地址:https://www.cnblogs.com/Lour688/p/13256490.html
那道题是这样的:(步步为零)步步为零(dp ??)
游戏者通常是从最下面的方格出发,按照如图 1.2所示的规则在表格中跳动,当游戏者跳到最顶端的方格时,游戏结束。在游戏未结束前,游戏者不允许跳到表格外。将游戏者跳到的 2?N?1个数字依次写下来,在每两个相邻的数字中间加上加号或减号,使得计算结果最接近零。例如对于图 1.1所示的表格,最好的跳动及计算方案是:\(7+8+(?5)+(?2)?5?1?2=0 或 7+10+(?7)?6+(?3)?3+2=0 或 7+10+(?5)?10?5+1+2=0 或 7+10+(?5)+(?2)?5?3?2=0。\)Input
Output
Sample Input
2
3 1
-3 5 7
6 10 -2 20
-7 -5 -8
10 8
7Sample Output
Hint
(本博客主要强调细节,好吧写完博客之后我觉得上句话并不恰当)
\(f[i][j][k]= 0 或 1\),\(f[i][j][k]= = 0\)表示最后一个数一直加到\(a[i][j]\)(还没加\(a[i][j]\))不能达到k,\(f[i][j][k] = = 1\)表示可以达到 \(k\)
我们不处理负数,所以对于\(k\),我们算出一个最大区间\([-mid,mid]\),然后每次求出来的和都向上平移mid以保证正数。
转移:(我们是从下向上转移/递推)
\(-> f[i-1][j][k+a[i][j]] = 1;\)
\(-> f[i-1][j+1][k+a[i][j] = 1;\)
\(-> f[i-1][j][k-a[i][j]] = 1;\)
\(-> f[i-1][j+1][k-a[i][j] = 1;\)
\(-> f[i-1][j][k+a[i][j]] = 1;\)
\(-> f[i-1][j-1][k+a[i][j] = 1;\)
\(-> f[i-1][j][k-a[i][j]] = 1;\)
\(-> f[i-1][j-1][k-a[i][j] = 1;\)
最后统计第0行的结果,不统计第一行是因为 \(f[1][1][k]\) 还没有算上 \(a[1][1]\) ,算上 \(a[1][1]\) 的结果转移到f[0][1][k]和 \(f[0][0][k]\) 中了。
每阶段只与上一阶段相关,滚动数组压维,每次转移完后没用了注意清零。Code
#include