POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )
题意 : 有 n 种蚂蚁,第 i 种蚂蚁有ai个,一共有 A 个蚂蚁。不同类别的蚂蚁可以相互区分,但同种类别的蚂蚁不能相互区别。从这些蚂蚁中分别取出S,S+1...B个,一共有多少种取法。
分析 :
实际就是要解决 => 从 n 种物品中取出 m 个有多少种取法 ( 同种无法区分 )
计数问题的 DP 定义必须保证不重复计数
这里定义 dp[i+1][j] => 从前 i 种物品中取出 j 个的组合数
根据定义为了从前 i 种物品中取出 j 个,可以从前 i-1 中取出 j-k 个并从 i 种中取出 k 个
即 dp[i+1][j] = ∑dp[i][j-k] 【 0 ≤ k ≤ min(j, ant[i]) 】
但是这个递推式的求和太耗时间,实际可以优化,考虑两种情况 j ≤ ant[i] 和 j > ant[i]
① j ≤ ant[i] ( 即 j-1 < ant[i] )
此时 ∑ 的上界 min( j, ant[i] ) = j ,将式子展开有 dp[i][0]+dp[i][1]+dp[i][2]...dp[i][j] ( k 从大到小枚举 )
将展开式的 dp[i][j] 取出来那么将得到 ∑dp[i][j-1-k] 【 0 ≤ k ≤ j-1 】( 其实这个就是 dp[i+1][j-1] !!! )
那么最后 dp[i+1][j] = dp[i+1][j-1] + dp[i][j]
② j > ant[i]
此时 ∑ 的上界 min( j, ant[i] ) = ant[i],将式子展开有 dp[i][j-ant[i]]+dp[i][j-ant[i]+1]...dp[i][j]
对比 ① 的结果,很明显如果用 ① 的结果 - dp[i][j-ant[i]-1] 就能得到上面的展开式了!
所以 ② 的情况下,dp[i+1][j] = ( dp[i+1][j-1] + dp[i][j] ) - dp[i][j-ant[i]-1]
#include<stdio.h>
#include<string.h>
using namespace std;
;
][];
];
int main(void)
{
int T, A, S, B;
while(~scanf("%d %d %d %d", &T, &A, &S, &B)){
memset(num, , sizeof(num));
; i<=A; i++)
scanf("%d", &temp),
num[temp-]++;
; i<=T; i++)
dp[i][] = ;
; i<T; i++){
; j<=B; j++){
- num[i] >= )
dp[i+][j] = (dp[i+][j-] + dp[i][j] - dp[i][j--num[i]] + mod)%mod;
else
dp[i+][j] = (dp[i+][j-] + dp[i][j])%mod;
}
}
;
for(int i=S; i<=B; i++)
ans = (ans + dp[T][i])%mod;
printf("%d\n", ans);
}
;
}
其实 DP 的阶段 ( 数组第一维 ) 只跟前一个有关系,故用滚动数组优化
#include<stdio.h>
#include<string.h>
using namespace std;
;
][];
];
int main(void)
{
int T, A, S, B;
while(~scanf("%d %d %d %d", &T, &A, &S, &B)){
memset(num, , sizeof(num));
; i<=A; i++)
scanf("%d", &temp),
num[temp-]++;
;
dp[idx][] = dp[idx^][] = ;
; i<T; i++,idx^=){
; j<=B; j++){
- num[i] >= )
dp[idx^][j] = (dp[idx^][j-] + dp[idx][j] - dp[idx][j--num[i]] + mod)%mod;
else
dp[idx^][j] = (dp[idx^][j-] + dp[idx][j])%mod;
}
}
;
for(int i=S; i<=B; i++)
ans = (ans + dp[idx][i])%mod;
printf("%d\n", ans);
}
;
}
POJ 3046 Ant Counting ( 多重集组合数 && 经典DP )的更多相关文章
- poj 3046 Ant Counting(多重集组合数)
Ant Counting Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) Total ...
- poj 3046 Ant Counting
Ant Counting Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4982 Accepted: 1896 Desc ...
- poj3046 Ant Counting——多重集组合数
题目:http://poj.org/problem?id=3046 就是多重集组合数(分组背包优化): 从式子角度考虑:(干脆看这篇博客) https://blog.csdn.net/viphong/ ...
- poj 3046 Ant Counting (DP多重背包变形)
题目:http://poj.org/problem?id=3046 思路: dp [i] [j] :=前i种 构成个数为j的方法数. #include <cstdio> #include ...
- POJ 3046 Ant Counting DP
大致题意:给你a个数字,这些数字范围是1到t,每种数字最多100个,求问你这些a个数字进行组合(不包含重复),长度为s到b的集合一共有多少个. 思路:d[i][j]——前i种数字组成长度为j的集合有多 ...
- poj 3046 Ant Counting——多重集合的背包
题目:http://poj.org/problem?id=3046 多重集合的背包问题. 1.式子:考虑dp[ i ][ j ]能从dp[ i-1 ][ k ](max(0 , j - c[ i ] ...
- POJ 3046 Ant Counting(递推,和号优化)
计数类的问题,要求不重复,把每种物品单独考虑. 将和号递推可以把转移优化O(1). f[i = 第i种物品][j = 总数量为j] = 方案数 f[i][j] = sigma{f[i-1][j-k], ...
- POJ 1160:Post Office 邮局经典DP
Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17168 Accepted: 9270 Desc ...
- 多重集组合数 简单dp
#include <cstdio> #include <iostream> using namespace std; +; +; +; ; int n,m,M; int a[m ...
随机推荐
- 如何保存不连着电脑跑monkey?如何跑多个APK的monkey?
哈喽,大家有没有遇到用真机跑monkey的时候,跑到一半结果小手一抖不小心把线碰掉了,结果报告就没获取到啦~ 今天就来解决这个问题 1.如何保存不连着电脑跑monkey? 1).输入命令进入shell ...
- 安装iamp模块,编译报错configure: error: Cannot find imap library (libc-client.a). Please check your c-client installation.
yum install libc-client-devel cd /root/lnmp1.0-full/php-5.3.17/ext/imap /usr/local/php/bin/phpize ./ ...
- SELECT 与 SET给标量赋值
本文转自 :https://blog.csdn.net/perddy/article/details/4033406 SQL Server推荐使用 SET 而不是 SELECT 对变量进行赋值.当表达 ...
- FTP-学习笔记(1)
1.简单的SFTP.FTP文件上传下载 SftpTools.java package com.lfy.mian; import com.jcraft.jsch.*; import java.io.Fi ...
- 使用extract-text-webpack-plugin插件后报错
如果你使用的webpack是4+版本,那么尝试运行npm install extract-text-webpack-plugin@next ,即可解决问题 然而最好的解决办法是在webpack4+的版 ...
- Java利用Base64编码和解码图片文件
1.编码与解码代码如下所示: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import jav ...
- Labview 错误1400-打包库封装类时将对类重命名导致
现象 今天遇到了一个神奇的BUG,主程序调用了一个包含类的打包库,打包库中将字符串还原为类句柄时报错. 调用程序结构如下:. 主程序中将类句柄转化为XML字符串程序如下: 打包库内将字符串还原为句柄程 ...
- 【模板】最长上升子序列(LIS)及其优化 & 洛谷 AT2827 LIS
最长上升子序列 传送门 题意 对于给定的一个n个数的序列,找到它的一个最长的子序列,并且保证这个子序列是由低到高排序的. 例如,1 6 2 5 4 6 8的最长上升子序列为1 2 4 6 8. 基本思 ...
- 数据库设计时,每个表要不要都设置自增主键ID!(转)
逻辑数据库设计 - 需要ID(谈主键Id) 本文的目标就是要确认那些使用了主键,却混淆了主键的本质而造成的一种反模式. 一.确立主键规范 每个了解数据库设计的人都知道,主键对于一张表来说是一个很重要, ...
- 四、JVM — 类文件结构
类文件结构 一 概述 二 Class 文件结构总结 2.1 魔数 2.2 Class 文件版本 2.3 常量池 2.4 访问标志 2.5 当前类索引,父类索引与接口索引集合 2.6 字段表集合 2.7 ...