标签:
题目大意 : 给出一行数 从中任选几个数成为一个字区间 如果存在一个这样的区间和 能够整除 m时 输出YES 否则输出NO
解题思路 : 任选数构成子序列 不能用指针查找法来做了 本题考虑DP 本题所设计的状态是前个数所能构成的子区间里是否有满足条件的
如果前 i -1 里已经有满足条件的 那 前 i 也就一定有了 如果前 i - 1 没有那就要看是否有能与当下把b[i] 组成 % m == 0 的
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int MaxN = 1e6, MN = 1e3;
int m, n, a[MaxN + 5], b[MaxN + 5];
bool f[MN + 5][MN + 5];
int main()
{
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
if(n >= m) printf("YES\n"); //如果是这样 那么肯定有 s[i] & m == s[j] % m 而s[j] - s[i] == m 所以一定存在这样的s[i] 能够 % m == 0
else
{
for(int i = 1; i <= n; i++)
{
b[i] = a[i] % m; // 转为a[i] 在m下的剩余系
}
for(int i = 1; i <= n; i++)
{
f[i][b[i]] = 1;
for(int j = 0; j <= m - 1; j++)
{
if(j != b[i])
{
f[i][j] = f[i - 1][j] || f[i - 1][(j - b[i] + m) % m]; // 注意这个转移方程 这是一个 || 运算
}
}
}
if(f[n][0]) printf("YES\n");
else printf("NO\n");
}
}
标签:
原文地址:http://www.cnblogs.com/123456YG/p/4999954.html