码迷,mamicode.com
首页 > 其他好文 > 详细

cf 319 div 2 Modulo Sum 数论+DP

时间:2015-09-11 23:33:12      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

                   Modulo Sum

题目抽象:给你你一个整数数组,能否从中取出一些树,使得他们的和能被m整除。

分析:见代码注释。

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int MS = 1000005;
 5 int n, m;
 6 int cnt[MS], r[MS], tem[MS];
 7 int main() {
 8     scanf("%d%d", &n, &m);
 9     memset(cnt, 0, sizeof(cnt));
10     for (int i = 0; i < n; i++) {
11         scanf("%d", &r[i]);
12         r[i] %= m;
13         cnt[r[i]]++;   //  统计不同余数的个数
14     }
15     memset(r, 0, sizeof(r));     //初始化余数i不能构成
16     for (int i = 0; i < m; i++) {
17         if (cnt[i] > 0) {      //处理余数i
18             int x = 1;
19             while (cnt[i] > 0) {
20                 int y = x < cnt[i] ? x : cnt[i];
21                 cnt[i] -= y;                  
22                 x *= 2;                //  倍增算法处理。
23                 int z = (i * y) % m;    //  y个余数i构成余数z.
24                 for (int j = 0; j < m; j++) {
25                     if (r[j])
26                         tem[(j + z) % m] = 1;    // 在余数j的基础上构成余数(j + z) %m
27                 }
28                 for (int j = 0; j < m; j++) {
29                     r[j] += tem[j];     //  更新能构成的余数
30                     tem[j] = 0;
31                 }
32                 r[z] = 1;     //余数z能构成
33             }
34             if (r[0] > 0)
35                 break;
36         }
37     }
38     if (r[0] > 0)
39         printf("YES\n");
40     else
41         printf("NO\n");
42     return 0;
43 }

 

cf 319 div 2 Modulo Sum 数论+DP

标签:

原文地址:http://www.cnblogs.com/hutaishi/p/4802205.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!