Codeforces 577B Modulo Sum
http://codeforces.com/problemset/problem/577/B
题意:有n个数,求有无一个子序列满足和是m的倍数
思路:用模下的背包做,发现n是十的六次方级别,但是有个神奇的性质,就是抽屉原理,当n大于等于m的时候,总会有sum[i]和sum[j]满足sum[i]%m=sum[j]%m,于是当n>=m的时候就可以特判掉,DP的复杂度就是O(n^2)的
总结:一定要记住,在模m下的前缀和这样的东西,一定要记得有抽屉原理!
然后这题的XX细节真是坑死我了
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 int a[2000005],f[2000005],n,m,g[2000005]; 7 int read(){ 8 int t=0,f=1;char ch=getchar(); 9 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 10 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 11 return t*f; 12 } 13 int main(){ 14 n=read();m=read(); 15 if (n>m){ 16 printf("YES"); 17 return 0; 18 } 19 for (int i=1;i<=n;i++) a[i]=read(); 20 for (int i=1;i<=n;i++){ 21 for (int j=1;j<=m;j++) g[j]=f[j]; 22 for (int j=m-1;j>=1;j--) 23 if (f[j]) 24 g[(a[i]%m+j)%m]=1; 25 g[a[i]%m]=1; 26 for (int j=0;j<=m;j++) f[j]=g[j]; 27 } 28 if (f[0]) printf("YES"); 29 else printf("NO"); 30 return 0; 31 }