POJ 3046 Ant Counting(递推,和号优化)
2024-09-03 23:32:59
计数类的问题,要求不重复,把每种物品单独考虑。
将和号递推可以把转移优化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+, maxa = 1e5+, mod = 1e6;
int f[][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[][] = f[][] = ; //不选方案数为1
for(int i = ; i <= T; i++){
int a = i&, b = a^;
for(int j = ; j <= B; j++){
if(j-c[i]>){
f[a][j] = ( f[a][j-] + f[b][j] - f[b][j--c[i]] ) % mod;
}else {
f[a][j] = ( f[a][j-] + f[b][j] ) % mod;
}
}
}
int sum = , *F = f[T&];
for(int i = S; i <= B; i++){
sum = (sum + F[i]) % mod;
}
printf("%d\n",sum<?sum+mod:sum);
return ;
}
最新文章
- BZOJ3771: Triple
- soj 2013年 Nanjing Slection
- 泛型数组列表 ArrayList
- github代码收集推荐
- plsql很好用的自定义设置【转载】
- JS弹出框插件zDialog再次封装
- Shell变量的定义与赋值操作注意事项
- jQuery : eq() vs get()
- VS2010运行正常的控制台程序在VS2015中出现乱码的解决方法
- 如何在android的mk文件添加依赖已经编译好的库
- Unix Shell中单引号、双引号字符、反斜杠、反引号的使用[转]
- (转) Crittercism: 在MongoDB上实现每天数十亿次请求
- linux下观看b站视频,解决字体乱码
- Unity3D-RPG项目实战(1):发动机的特殊文件夹
- git常用基本命令
- 1_mysql_认识
- 理解标准盒模型和怪异模式&;box-sizing属性
- 域名解析到Nginx服务器项目上
- 根据http获取的String数据,String数据中含有其他的字符时
- 数据挖掘标准规范之CRISP-DM基础