POJ 3046 Ant Counting(递推,和号优化)
2015-10-17 12:38
381 查看
计数类的问题,要求不重复,把每种物品单独考虑。
将和号递推可以把转移优化O(1)。
f[i = 第i种物品][j = 总数量为j] = 方案数
f[i][j] = sigma{f[i-1][j-k],(k = [0,min(j,c[i])])}
把和号展开
f[i][j] : j-0,j-1,...,j-a[i]
f[i][j-1] : j-1,j-2,...,j-a[i]-1
中间部分是一样的可以避免重复计算。
将和号递推可以把转移优化O(1)。
f[i = 第i种物品][j = 总数量为j] = 方案数
f[i][j] = sigma{f[i-1][j-k],(k = [0,min(j,c[i])])}
把和号展开
f[i][j] : j-0,j-1,...,j-a[i]
f[i][j-1] : j-1,j-2,...,j-a[i]-1
中间部分是一样的可以避免重复计算。
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> //#include<bits/stdc++.h> using namespace std; int T, A, S, B; const int maxt = 1e3+5, maxa = 1e5+5, mod = 1e6; int f[2][maxa]; int c[maxt]; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif scanf("%d%d%d%d",&T,&A,&S,&B); for(int i = A; i--;){ int x; scanf("%d",&x); c[x]++; } f[0][0] = f[1][0] = 1; //不选方案数为1 for(int i = 1; i <= T; i++){ int a = i&1, b = a^1; for(int j = 1; j <= B; j++){ if(j-c[i]>0){ f[a][j] = ( f[a][j-1] + f[b][j] - f[b][j-1-c[i]] ) % mod; }else { f[a][j] = ( f[a][j-1] + f[b][j] ) % mod; } } } int sum = 0, *F = f[T&1]; for(int i = S; i <= B; i++){ sum = (sum + F[i]) % mod; } printf("%d\n",sum<0?sum+mod:sum); return 0; }
相关文章推荐
- iframe跨域
- Pjax.js防刷新技术
- 扩展欧几里德算法解二元一次方程之B - 青蛙的约会
- hdoj Hat’s Words 1247 (字典树 判断两个字符串能否组成另一个字符串) 好题
- 关于apktool反编译出错Error occured at code address 0的解决办法
- 微信公众号80端口映射详解(一)
- 万科2015苏州城市乐跑音乐节昨日在太湖国际会议中心开跑
- Java中 构造函数与初始化块的执行顺序
- c++11特性之正则表达式
- c++11特性之正则表达式
- linux课本第81页的程序
- Redis Scan命令
- Android无需权限显示悬浮窗, 兼谈逆向分析app
- uiTableView 默认选中并加载数据
- Objective-C 程序设计 第三章
- PostGreSQL数据库检查(4)
- 持续更新线上问题及解决方案
- 1007. 素数对猜想 (20)
- Git远程操作详解
- VCSA 5.5升级至VCSA6.0