• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
爱花丶
博客园    首页    新随笔    联系   管理    订阅  订阅

code froce 577B DP

给两个数n(n <= 1e6), m ( m <= 1e3 ), 问能否在n个数里找到一些数 让他们的和相加能被m整除

思路: 把所有的n变为在m的剩余系下的数

1. n > m 此时在m的剩余系下一定存在两个相等的数 那他们之差一定是0 所以此时一定存在能被m整除 (抽屉原理)

2. n <= m

跟01背包问题类似 

DP设计的转移方程为

f[i][j] = f[i - 1][j] || f[i - 1][(j - a + m) % m]

前一个式子指在前面的所有数中是否存在和被m整除

第二个式子指在前面所有数中是否存在一个和加上当前这个数字能被m整除 (j != a)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int MaxN = 1000;
 8 int a, n, m;
 9 bool f[MaxN + 5][MaxN + 5];
10 
11 int main()
12 {
13     scanf("%d %d", &n, &m);
14     if (n > m)
15     {
16         printf("YES");
17         return 0;
18     }
19     else
20     {    
21         for (int i = 1; i <= n; i++)
22         {
23             scanf("%d", &a); a %= m;
24             f[i][a] = 1;
25             for (int j = 0; j <= m - 1; j++)
26             if (j != a) f[i][j] = f[i - 1][j] || f[i - 1][(j - a + m) % m];
27         }
28         printf(f[n][0] ? "YES" : "NO");
29     }
30 }

 

posted @ 2015-11-27 09:49  爱花丶  阅读(110)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3