HDU 5464 Clarke and problem 动态规划
2016-03-09 23:42
363 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5464Clarke and problem
Accepts: 130Submissions: 781
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
克拉克是一名人格分裂患者。某一天,克拉克分裂成了一个学生,在做题。 突然一道难题难到了克拉克,这道题是这样的: 给你nn个数,要求选一些数(可以不选),把它们加起来,使得和恰好是pp的倍数(00也是pp的倍数),求方案数。 对于nn很小的时候,克拉克是能轻易找到的。然而对于nn很大的时候,克拉克没有办法了,所以来求助于你。
输入描述
第一行一个整数T(1 \le T \le 10)T(1≤T≤10),表示数据的组数。 每组数据第一行是两个正整数n, p(1 \le n, p \le 1000)n,p(1≤n,p≤1000)。 接下来的一行有nn个整数a_i(|a_i| \le 10^9)ai(∣ai∣≤109),表示第ii个数。
输出描述
对于每组数据,输出一个整数,表示问题的方案数,由于答案很大,所以求出对10^9+7109+7的答案即可。
输入样例
1 2 3 1 2
输出样例
2
Hint
有两种方案:什么也不选;全都选。
题解:
dp,01背包,对每个数考虑选和不选两种转移方案,这样就能统计所有的子序列了,然后用取模的方式两降低空间规模。代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long LL; const int maxn=1111; const int mod=1e9+7; int n,q; int a[maxn]; LL dp[maxn][maxn]; void init(){ memset(dp,0,sizeof(dp)); dp[0][0]=1; } int main(){ int tc; scanf("%d",&tc); while(tc--){ init(); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=n;i++){ for(int j=0;j<q;j++){ //不选第i个数 dp[i][j]+=dp[i-1][j]; dp[i][j]%=mod; //选第i个数 dp[i][((j+a[i])%q+q)%q]+=dp[i-1][j]; dp[i][((j+a[i])%q+q)%q]%=mod; } } printf("%lld\n",dp [0]); } return 0; }
View Code
相关文章推荐
- Bomb(数位DP)
- eventlet引发的学习:协程
- Poj2831 树链剖分||次小生成树
- 转点信息
- 不同类型的变量与零值比较的方法
- jquery datatables 一些有用的用法
- BZOJ 1854 游戏
- 12个球一个天平,现知道只有一个和其它的重量不同,问怎样称才能用三次就找到那个球
- 802.1W 感悟以及和802.1D对比
- 如何在ubuntu开启ssh服务-使 SecureCRT远程登录
- 如何在ubuntu开启ssh服务-使 SecureCRT远程登录
- locale命令
- const与sizeof
- 如何在ubuntu开启ssh服务-使 SecureCRT远程登录
- DTD/XXE 攻击笔记分享
- hdu-5583 Kingdom of Black and White(数学,贪心,暴力)
- 头文件
- [Offer收割机]编程练习赛1
- MVC基本开发介绍 (1)列表展示
- PAT- Student List for Course (25)