BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)

BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp),第1张

概述本文章向大家介绍BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp),需要的朋友可以参考一下

题意

题目描述的很清楚。。。

有一天,贝茜无聊地坐在蚂蚁洞前看蚂蚁们进进出出地搬运食物.很快贝茜发现有些蚂蚁长得几乎一模一样,于是她认为那些蚂蚁是兄弟,也就是说它们是同一个家族里的成员.她也发现整个蚂蚁群里有时只有一只出来觅食,有时是几只,有时干脆整个蚁群一起出来.这样一来,蚂蚁们出行觅食时的组队方案就有很多种.作为一头有数学头脑的奶牛,贝茜注意到整个蚂蚁群由T(1≤T≤1000)个家族组成,她将这些家族按1到T依次编号.编号为i的家族里有Ni(1≤Ni≤100)只蚂蚁.同一个家族里的蚂蚁可以认为是完全相同的.

如果一共有S,S+1….,B(1≤S≤B≤A)只蚂蚁一起出去觅食,它们一共能组成多少种不同的队伍呢?注意:只要两支队伍中所包含某个家族的蚂蚁数不同,我们就认为这两支队伍不同.由于贝茜无法分辨出同一家族的蚂蚁,所以当两支队伍中所包含的所有家族的蚂蚁数都相同时,即使有某个家族换了几只蚂蚁出来,贝茜也会因为看不出不同而把它们认为是同一支队伍.

Sol

裸的dp比较好想,$f[i][j]$表示前$i$个家族,选了$j$个蚂蚁

转移的时候枚举这个选了几个

这玩意儿显然可以用前缀和优化,空间问题用滚动数组处理

有一个小trick:在处理前缀和的时候我们可以保留下本层dp的信息,所以滚动数组是不需要的,具体看代码吧

#include

#include

#include

#define pt(x) printf("%d ",x);

using namespace std;

const int MAXN = 1e5 + 10,mod = 1000000;

inline int read() {

char c = getchar(); int x = 0,f = 1;

while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}

while(c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar();

return x * f;

}

int T,A,L,R;

int num[MAXN],f[MAXN],sum[MAXN],s;

int main() {

T = read(); A = read(); L = read(); R = read();

for(int i = 1; i <= A; i++) num[read()]++;

for(int i = 0; i <= num[1]; i++) sum[i] = 1;

for(int i = 1; i <= T; i++) {

s += num[i];

for(int j = 0; j <= s; j++) {

int x = j - num[i] - 1;

f[j] = sum[j];

if(x >= 0) f[j] = (f[j] - sum[x] + mod) % mod;

}

sum[0] = f[0];

for(int j = 1; j <= s + num[i + 1]; j++)

sum[j] = (sum[j - 1] + f[j]) % mod;

if(i != T) memset(f,sizeof(f));

}

int ans = 0;

for(int i = L; i <= R; i++)

(ans += f[i]) %= mod;

printf("%d",ans % mod);

return 0;

}

/*

3 5 1 5

1

2

2

1

3

*/

总结

以上是内存溢出为你收集整理的BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)全部内容,希望文章能够帮你解决BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(dp)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1264688.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存