CF #319 B Modulo Sum
2015-09-13 22:55
369 查看
这是一道不错的dp题。
我们用dp[i][j]来代表前j个数能够达到的对m取余的余数,而我们发现j只与j-1有关,可以用滚动数组。那么我们只需要用类似背包的dp来计算出所有可能的结果即可。
我们用dp[i][j]来代表前j个数能够达到的对m取余的余数,而我们发现j只与j-1有关,可以用滚动数组。那么我们只需要用类似背包的dp来计算出所有可能的结果即可。
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<algorithm> #include<iomanip> #include<vector> #include<time.h> #include<queue> #include<stack> #include<iterator> #include<math.h> #include<stdlib.h> #include<limits.h> #include<map> #include<set> #include<bitset> //#define ONLINE_JUDGE #define eps 1e-5 #define INF 0x7fffffff #define FOR(i,a) for((i)=0;i<(a);(i)++) #define MEM(a) (memset((a),0,sizeof(a))) #define sfs(a) scanf("%s",a) #define sf(a) scanf("%d",&a) #define sfI(a) scanf("%I64d",&a) #define pf(a) printf("%d\n",a) #define pfI(a) printf("%I64d\n",a) #define pfs(a) printf("%s\n",a) #define sfd(a,b) scanf("%d%d",&a,&b) #define sft(a,b,num) scanf("%d%d%d",&a,&b,&num) #define for1(i,a,b) for(int i=(a);i<b;i++) #define for2(i,a,b) for(int i=(a);i<=b;i++) #define for3(i,a,b)for(int i=(b);i>=a;i--) #define MEM1(a) memset(a,0,sizeof(a)) #define MEM2(a) memset(a,-1,sizeof(a)) #define ll __int64 const double PI=acos(-1.0); template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} template<class T> inline T Min(T a,T b){return a<b?a:b;} template<class T> inline T Max(T a,T b){return a>b?a:b;} using namespace std; //#pragma comment(linker,"/STACK:1024000000,1024000000") int n,m; int p; #define M 1110 #define N 1000010 #define Mod 1000000000 #define p(x,y) make_pair(x,y) const int MAX_len=550; int isp[M]; vector<int> prime; int dp[1010][2]; int a ; int main(){ #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(sfd(n,m)!=EOF){ int flag=0; for(int i=0;i<n;i++){ sf(a[i]); a[i] %= m; if(a[i] == 0) flag=1; } if(flag){ printf("YES\n"); continue; } int p=1; memset(dp,0,sizeof dp); for(int i=0;i<n;i++){ dp[a[i]][p] = 1; //能够到达a[i] for(int j=0;j<m;j++){ //循环所有可能的对m取余的结果 if(dp[j][p^1]){ //如果j这个结果能够在前面取到 dp[(a[i]+j)%m][p] = 1; //那么到了a[i],我们可以取a[i],余数就变成了(a[i]+j)%m dp[j][p] = 1; //也可以不取a[i],余数就还是 保持j不变 } } if(dp[0][p]){ //前p个数能够取到对m取余为0的和结果 flag=1; break; } p ^= 1; } if(flag) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- codeforces 577B. Modulo Sum 解题报告
- 以最快的速度求出Fibonacci 序列的第n项
- Mysql的主从复制功能
- web设计——card
- 计划任务工具-windows
- 毕达哥拉斯的故事
- Java的线程状态切换
- hdu 5437Alisha’s Party(优先队列)
- 录像 的一些思考总结--1
- 检测内存泄露、多线程gdb调试(core)、内核态用户态的通信
- hdu 5437Alisha’s Party(优先队列)
- iOS App开发准备工作—开发环境准备
- 用GL画出人物的移动路径
- 男人就要对自己狠一点
- HDU 5443 The Water Problem 解题报告(如题)
- searchRange
- MySQL 事件跟踪器 , MySQL 无须重启服务 跟踪 SQL , 也无须配置日志
- 听闫老师讲“换个角度看‘面向对象’”
- 滴滴打车:天价补贴背后的惊人秘密
- Linux 基本命令学习