题目链接:Problem - 577B - Codeforces Modulo Sum
求n个数中是否存在任意个数的和恰好能整除m,n的范围是1e6,m的范围是1e3。
抽屉原理可以证明当n>m,是一定存在的,因为n个数的模后前缀和肯定有相同的,而相同则表示这两个相同的模之间的连续子段和是能够整除m的。
剩下的可以用dp来考虑了,dp[i][j]表示前i个数中任意个数相加模m后的值为j的情况是否已经存在了。
#include<bits/stdc++.h> using namespace std; int n,m,a[1000005],f[1005][1005]; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[i]=a[i]%m; } bool flag=false; if(n>m) printf("YES\n"); else{ f[0][0]=1;//初始化 for(int i=1;i<=n&&!flag;i++){ for(int j=0;j<m&&!flag;j++){ int res=(j-a[i]+m)%m; if(f[i-1][res]){//判断是否能够状态转移 f[i][j]=1; if(j==0) flag=true; } if(f[i-1][j]) f[i][j]=1; } } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }