![0ea21119ca1b4c1fc4926623050d491e.png](https://i-blog.csdnimg.cn/blog_migrate/da022b6a4a0b9d0b132f5105ae73c0c4.jpeg)
【题目描述】3531:判断整除 By HackPluto
描述
一个给定的正整数序列,在每个数之前都插入+号或-号后计算它们的和。比如序列:1、2、4共有8种可能的序列:
(+1) + (+2) + (+4) = 7
(+1) + (+2) + (-4) = -1
(+1) + (-2) + (+4) = 3
(+1) + (-2) + (-4) = -5
(-1) + (+2) + (+4) = 5
(-1) + (+2) + (-4) = -3
(-1) + (-2) + (+4) = 1
(-1) + (-2) + (-4) = -7
所有结果中至少有一个可被整数k整除,我们则称此正整数序列可被k整除。例如上述序列可以被3、5、7整除,而不能被2、4、6、8……整除。注意:0、-3、-6、-9……都可以认为是3的倍数。
输入
输入的第一行包含两个数:N(2 < N < 10000)和k(2 < k< 100),其中N代表一共有N个数,k代表被除数。第二行给出序列中的N个整数,这些整数的取值范围都0到10000之间(可能重复)。
输出
如果此正整数序列可被k整除,则输出YES,否则输出NO。(注意:都是大写字母)
![0f931777926fd8574298a39eac920739.png](https://i-blog.csdnimg.cn/blog_migrate/cc22a1fee38b5bb9a0d12999ff8fa273.png)
一、题意分析
本题的输入为两部分,一个是N,一个是K,N代表着有N个数,K代表要被整除的数,本题的意思就是输入N个正整数(划重点,输入的只有正数)然后在每个数前面加+ 或— 判断最后的和能不能被K整除。因为这个题是在动态规划的章节的,所以在思考的时候就在往动态规划的地方考虑,如果我不知道这个是在考动态规划,我可能会使用枚举法将每一种情况都穷举出来然后判断,但是看一下这个题的数据规模,N <= 10000,也就是说我要枚举2^10000次 ,这显然是超时的。所以对于这个题来说,动态规划可能是最好的方法了。
二、算法说明
既然已经知道了是使用动态规划,那么对于动态规划来说最重要的就是写出状态转移方程了,那这个题怎么写状态转移方程呢,我们可以使用一个数组 f[i][j] 来代表序列前i个数模k的余数是不是j,是的话这一元素的值为1否则为0。显然 f[i][j] 中的j就是序列中第一个元素模k的值还有第一个元素的负数模k的值,这个题中如何处理负数是一个重点,因为负数的余数也是负数,怎么用下标存呢,这里介绍一个技巧,先将这个负数余数加上k再取模,为什么呢,我们发现对于一串数求和算模k的余数我们用这个方法求的余数是一样的
三、数据结构
数组
四、代码与调试
![9526a2ce17d48e4ea1bd6ac8e6b0cc54.png](https://i-blog.csdnimg.cn/blog_migrate/f52744c21869900b1053d1d7967eccdc.jpeg)