关于 modulo 操作的问题

2019-08-11 12:52:35 +08:00
 AslanFong

今天做题,遇到大整数累加遇到 modulo 的问题,想请教一下大家,题目说 Return the number of possible ways modulo 10^9 + 7 to roll the dice so the sum of the face up numbers equals target.

我尝试了两种方案:

m = (int)1e9 + 7;
//1
for(int n = 1; n <= f && n <= j; n++) {
    	dp[i][j] += dp[i - 1][j - n] % m;
    }
//2
for(int n = 1; n <= f && n <= j; n++) {
    	dp[i][j] += dp[i - 1][j - n];
        dp[i][j] %= m;
    }

第一种的结果是错的,第二种的结果是对的。实在是不懂,modulo 操作的顺序会怎么改变数值呢?对于多个数累加,到底要在哪一步 modulo 操作才是对的呢?有没有什么范式之类的?

谢谢大家!

660 次点击
所在节点    问与答
2 条回复
lcdtyph
2019-08-11 13:42:29 +08:00
因为两种写法不等价
第一种相当于 dp[i][j] = (dp[i][j] + (dp[i-1][j-n] % m))
第二种相当于 dp[i][j] = ((dp[i][j] + d[i-1][j-n]) % m)
看到区别了吗,第二种模了最后的结果,第一步只模了其中一个加数。

举个例子,假设 dp[i][j] == 1e9+6, dp[i-1][j-n] == 8
那么第一种写法算出来的 dp[i][j] == 1e9 + 14 因为没有最终取模。

多个数累加,最后一步取模是必须的,如果你担心中间结果溢出,还可以在每一次加完都取模一次。
AslanFong
2019-08-11 14:10:49 +08:00
@lcdtyph 十分感谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/590912

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX