POJ 3046
题目大意:蚂蚁牙黑,蚂蚁牙红:有A只蚂蚁,来自T个家族,分别记为ant[i]个。同一个家族的蚂蚁长得一样,但是不同家族的蚂蚁牙齿颜色不同。任取n只蚂蚁(S <= n <= B),求能组成几种集合?
状态:dp[i][j]:前i种中选j个可以组成的种数
决策:第i种选k个,k<=ant[i] && j-k>=0
转移:dp[i][j]=Σdp[i-1][j-k]

#include<stdio.h>
#include<string.h>
int dp[1005][10050];
int num[10050];
int main(){
int n,m,a,b,x;
while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){
memset(num,0,sizeof(num));
for(int i=0;i<m;i++){
scanf("%d",&x);
num[x]++;
}
memset(dp,0,sizeof(dp));
for(int i=0;i<=num[1];i++) dp[1][i]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=b;j++){
for(int k=0;k<=num[i];k++){
if(j>=k) {
dp[i][j]+=dp[i-1][j-k];
dp[i][j]%=1000000;
}
}
}
}
int ans=0;
for(int i=a;i<=b;i++){
ans+=dp[n][i];
ans%=1000000;
}
printf("%d\n",ans);
}
return 0;
}

还有一种
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-ant[i]-1]

#include<iostream>
using namespace std;
#define MOD 1000000
int T, A, S, B;
int ant[1005];
int dp[2][100000];
int ans;
int main()
{
scanf("%d%d%d%d", &T, &A, &S, &B);
for (int i = 1; i <= A; i++)
{
int aa;
scanf("%d", &aa);
ant[aa]++;
}
dp[0][0] = dp[1][0] = 1;
for (int i = 1; i <= T; i++)
for (int j = 1; j <= B; j++)
if (j - ant[i] - 1 >= 0) dp[i % 2][j] = (dp[(i - 1) % 2][j] + dp[i % 2][j - 1] - dp[(i - 1) % 2][j - ant[i] - 1] + MOD) % MOD; //在取模时若出现了减法运算则需要先+Mod再对Mod取模,防止出现负数(如5%4-3%4为负数)
else dp[i % 2][j] = (dp[(i - 1) % 2][j] + dp[i % 2][j - 1]) % MOD;
for (int i = S; i <= B; i++)
ans = (ans + dp[T % 2][i]) % MOD;
printf("%d\n", ans);
return 0;
}

POJ 3046的更多相关文章
- poj 3046 Ant Counting (DP多重背包变形)
题目:http://poj.org/problem?id=3046 思路: dp [i] [j] :=前i种 构成个数为j的方法数. #include <cstdio> #include ...
- poj 3046 Ant Counting——多重集合的背包
题目:http://poj.org/problem?id=3046 多重集合的背包问题. 1.式子:考虑dp[ i ][ j ]能从dp[ i-1 ][ k ](max(0 , j - c[ i ] ...
- DP:Ant Counting(POJ 3046)
数蚂蚁 题目大意:一只牛想数蚂蚁,蚂蚁分成很多组,每个组里面有很多只蚂蚁,现在问你有多少种组合方式 (说白了就是问1,1,1,...,2...,3...,4...)这些东西有多少种排列组合方式 这一道 ...
- poj 3046 Ant Counting
Ant Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4982 Accepted: 1896 Desc ...
- POJ 3046 Ant Counting DP
大致题意:给你a个数字,这些数字范围是1到t,每种数字最多100个,求问你这些a个数字进行组合(不包含重复),长度为s到b的集合一共有多少个. 思路:d[i][j]——前i种数字组成长度为j的集合有多 ...
- poj 3046 Ant Counting(多重集组合数)
Ant Counting Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total ...
- POJ 3046 Ant Counting(递推,和号优化)
计数类的问题,要求不重复,把每种物品单独考虑. 将和号递推可以把转移优化O(1). f[i = 第i种物品][j = 总数量为j] = 方案数 f[i][j] = sigma{f[i-1][j-k], ...
- 【POJ - 3046】Ant Counting(多重集组合数)
Ant Counting 直接翻译了 Descriptions 贝西有T种蚂蚁共A只,每种蚂蚁有Ni只,同种蚂蚁不能区分,不同种蚂蚁可以区分,记Sum_i为i只蚂蚁构成不同的集合的方案数,问Sum_k ...
- POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )
题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁.不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别.从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法. 分析 : ...
随机推荐
- asp.net mvc5 step by step(二)——Data Annotations(data 注释)
以下使用在Entity Framework Code First Entity Framework Code First 利用一种被称为约定(Conventions)优于配置(Configura ...
- Oracle 缓存命中率问题一则(里面有个问题咨询大佬们)
近日,核心数据库频繁抱出数据库缓存命中率过低,于是开始进行排查. 1.监控软件告警信息 2.抓取告警时间段内的awr报告进行分析 3.execute与parse命中率过低,说明分析(硬解析与软解析)的 ...
- oracle 数据库密码生产同步模拟环境 ,随记常用命令
1.查看当前open用户 select username,account_status,expiry_date,profile from dba_users; 2.查看目前的密码过期策略 select ...
- JavaScript面向对象(封装)
阮一峰的网络日志 1.生成实例对象的原始模式 var People = { name : '', age : '' } 根据这个原型对象生成两个实例对象 var people1 = {}; peopl ...
- 本地打jar包到本地的Maven出库
1.命令行输入 mvn install:install-file -DgroupId=jar包的groupId -DartifactId=jar包的artifactId -Dversion=jar包的 ...
- Linux面试笔试题带答案【详解】
一.填空题:1. 在Linux系统中,以 ,该文件属性是 目录.8. 前台起动的进程使用 Ctrl+c 终止.9. 静态路由设定后,若网络拓扑结构发生变化,需由系统管理员修改路由的设置.10. 网络管 ...
- svn出现目标计算机积极拒绝无法链接
这是由于没有启动服务器端监控的原因,只需要执行以下代码即可 svnserve -d --listen-port 8000 -r /opt/svn
- laravel 闪存
https://blog.csdn.net/ckdecsdn/article/details/52083093
- python remove跟pop的区别
remove根据值来删除 li=[1,2,3,4] li.pop[0] li.remove['] 或者是a=li[-1]li.remove(a) pop是根据索引来删除
- html 的radio单选框如何实现互斥------radio只是input的type属性
先看看没有互斥的情况: <html> <body> 男性:<input type="radio" id="male" /> ...