思路: dp
分析:1 又是一道看了题解还不懂怎么个回事的题,然后各种YY之后有点感觉
2 题目要求的是在n个数中间插入n-1个的+或-使得结果能否被k整除
3 看一个数学的公式(a+b)%k = a%k+b%k,按照网上的题解dp[i][j]表示的是前i个数运算能否得到模为j,如果可以则dp[i][j] = true,否则为false
4 那么如果dp[i-1][j] = true,则可以知道dp[i][(j+arr[i])%k]] = true , dp[i][(j-arr[i])%k]] = true。怎么理解这个状态转移方程呢,因为对于arr[i]这个数我们可以加也可以减,所以说有两种的情况
5 由于题目要求的是模,所以我们只要把所有的负数全部搞成正数即可。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX = 110;
const int MAXN = 10010;
int n , k;
bool dp[MAXN][MAX];
int main(){
int num;
while(scanf("%d%d" , &n , &k) != EOF){
memset(dp , false , sizeof(dp));
scanf("%d" , &num);
dp[0][abs(num)%k] = true;
for(int i = 1 ; i < n ; i++){
scanf("%d" , &num);
num = abs(num)%k;
for(int j = 0 ; j < k ; j++){
if(dp[(i-1)%2][j]){
dp[i%2][(j+num)%k] = true;
dp[i%2][(j-num+k)%k] = true;
}
}
}
if(dp[(n-1)%2][0])
puts("Divisible");
else
puts("Not divisible");
}
return 0;
}