标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 11151 | Accepted: 3993 |
Description
Input
Output
Sample Input
4 7 17 5 -21 15
Sample Output
Divisible
题意:输入n个数,通过添加+和-能否是的结果对k取余为0
思路:智商再次背碾压
首先一个数,不用说,第一个数之前不用加符号就是本身,那么本身直接对K取余,
那么取17的时候有个余数为2
然后来了一个5,
(2 + 5)对7取余为0
(2 - 5)对7取余为4(将取余的负数变正)
那么前2个数有余数0和4
再来一个-21
(0+21)对7取余为0
(0-21)对7取余为0
(4+21)对7取余为4
(4-21)对7取余为4
再来一个-15同样是这样
(0+15)%7 = 1
(0-15)%7 = 6
(4+15)%7 = 5
(4-15)%7 = 3
同理可以找到规律,定义dp[i][j]为前i个数进来余数等于j是不是成立,1为成立,0为不成立
那么如果dp[N][0]为1那么即可以组成一个数对K取余为0
初始化dp为0
然后dp[1][a[1]%k] = 1
for i = 2 to N do
for j = 0 to K do
if(dp[i - 1][j])
dp[i][(j + a[i])%k] = 1;
dp[i][(j - a[i])%k] = 1;
if end
for end
for end
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int dp[10000 + 10][100 + 10],a[10000 + 10]; 7 int n,k; 8 int mod(int x) 9 { 10 if(x < 0) 11 { 12 return x + k; 13 } 14 else 15 return x; 16 } 17 int main() 18 { 19 while(scanf("%d%d", &n, &k) != EOF) 20 { 21 for(int i = 1; i <= n; i++) 22 scanf("%d", &a[i]); 23 memset(dp, 0, sizeof(dp)); 24 dp[1][ mod(a[1] % k) ] = 1; 25 for(int i = 2; i <= n; i++) 26 { 27 for(int j = 0; j <= k; j++) 28 { 29 if(dp[i - 1][j]) 30 { 31 dp[i][ mod((j + a[i]) % k)] = 1; 32 dp[i][ mod((j - a[i]) % k)] = 1; 33 } 34 } 35 } 36 if(dp[n][0]) 37 printf("Divisible\n"); 38 else 39 printf("Not divisible\n"); 40 } 41 42 43 return 0; 44 }
标签:
原文地址:http://www.cnblogs.com/zhaopAC/p/5055085.html