POJ 3046 Ant Counting 简单DP 挑战程序设计实战习题
2016-07-28 13:09
316 查看
题目点这里
题目大意是给出T种数字,每种会有一定数量
问你用它们构成一些长度的序列,可以用相同数字,问从S长度到B长度共有多少种组合,结果取最后六位数。
有经验的老司机一下就知道是
dp[i][j]为前i种数字组成j长度的总数
递推方程为
dp[i][j] = sigma(dp[i-1][j-k] ) k 的取值范围是从1到第i个数字的个数
有sigma就知道可以用前缀和算出来优化时间
空间的话可以看出d[i]只和d[i-1]有关,用滚动数组就好了
下面是代码
题目大意是给出T种数字,每种会有一定数量
问你用它们构成一些长度的序列,可以用相同数字,问从S长度到B长度共有多少种组合,结果取最后六位数。
有经验的老司机一下就知道是
dp[i][j]为前i种数字组成j长度的总数
递推方程为
dp[i][j] = sigma(dp[i-1][j-k] ) k 的取值范围是从1到第i个数字的个数
有sigma就知道可以用前缀和算出来优化时间
空间的话可以看出d[i]只和d[i-1]有关,用滚动数组就好了
下面是代码
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int mod = 1000000; int num[1110]; int sum[111111]; int dp[2][111111]; int up[1110]; int main() { int T,A,S,B; scanf("%d%d%d%d",&T,&A,&S,&B); for(int i=0,x;i<A;i++){ scanf("%d",&x); num[x]++; } up[0] = 0; for(int i=1;i<=T;i++) up[i] = up[i-1] + num[i]; memset(dp,0,sizeof(dp)); dp[0][0] = 1; for(int i=1;i<=T;i++){ int nxt = i%2; int pre = (i-1)%2; sum[0] = dp[pre][0]; for(int j=1;j<=up[i];j++) sum[j] = (sum[j-1]+dp[pre][j])%mod; for(int j=0;j<=up[i];j++) { int tmp = max(0,j-num[i]); dp[nxt][j] = ((tmp==0)? sum[j] : (sum[j] - sum[tmp-1] + mod)); dp[nxt][j] %= mod; } } int ans = 0; for(int i=S;i<=B;i++) ans = (ans+dp[T%2][i])%mod; printf("%d\n",ans); return 0; }
相关文章推荐
- maven使用经验集
- MySQL 优化
- Google排名优化的几个影响因素
- DB2优化(简易版)
- Mysql limit 优化,百万至千万级快速分页 复合索引的引用并应用于轻量级框架
- C#中尾递归的使用、优化及编译器优化
- 对优化Ruby on Rails性能的一些办法的探究
- 优化Ruby脚本效率实例分享
- 样式表CSS布局经验
- 路由器之基本维护经验
- Asp编码优化技巧
- 如何监测和优化OLAP数据库
- mysql -参数thread_cache_size优化方法 小结
- MySQL数据库优化技术之配置技巧总结
- Oracle数据库中SQL语句的优化技巧
- 深入学习SQL Server聚合函数算法优化技巧
- MySQL常见的底层优化操作教程及相关建议
- 详解mysql的limit经典用法及优化实例
- 数据库学习建议之提高数据库速度的十条建议
- oracle数据库sql的优化总结