[BZOJ1630/2023][Usaco2005 Nov]Ant Counting 数蚂蚁(dp)
2016-10-24 13:07
357 查看
题目描述
传送门题解
题目实际上是要我们求“有重复元素的组合数”问题,这道dp模型非常经典。首先将数预处理,将相同的元素合并成一项,并记录每一种元素的数量cnt[i]。设f(i,j)表示在前i种元素中选出j个的方案数。那么f(i,j)=∑k=0min(cnt[i],j)f(i−1,j−k)
但是裸的dp的话时间和空间都是爆掉的。空间方面加一个滚动数组就可以了,时间可以用前缀和优化。
代码
暴力dp#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 1005 #define Mod 1000000 int t,a,s,b,ans,n; int fa[N],cnt[N],sc[N],f[N][N]; int main() { scanf("%d%d%d%d",&t,&a,&s,&b); for (int i=1;i<=a;++i) { scanf("%d",&fa[i]); cnt[fa[i]]++; } sort(fa+1,fa+a+1); n=unique(fa+1,fa+a+1)-fa-1; for (int i=1;i<=n;++i) sc[i]=sc[i-1]+cnt[fa[i]]; f[0][0]=1; for (int i=1;i<=n;++i) for (int j=0;j<=sc[i];++j) for (int k=0;k<=min(j,cnt[fa[i]]);++k) f[i][j]=(f[i][j]+f[i-1][j-k])%Mod; for (int i=s;i<=b;++i) ans=(ans+f [i])%Mod; printf("%d\n",ans); }
AC code
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define N 100005 #define Mod 1000000 int t,a,s,b,ans,n; int fa[N],cnt[N],sc[N],f[2][N],ss[2][N]; int main() { scanf("%d%d%d%d",&t,&a,&s,&b); for (int i=1;i<=a;++i) { scanf("%d",&fa[i]); cnt[fa[i]]++; } sort(fa+1,fa+a+1); n=unique(fa+1,fa+a+1)-fa-1; for (int i=1;i<=n;++i) sc[i]=sc[i-1]+cnt[fa[i]]; f[0][0]=1; for (int i=0;i<=100000;++i) ss[0][i]=1; for (int i=1;i<=n;++i) { memset(f[i&1],0,sizeof(f[i&1])); memset(ss[i&1],0,sizeof(ss[i&1])); for (int j=0;j<=sc[i];++j) { int x=ss[(i-1)&1][j]; f[i&1][j]=(f[i&1][j]+ss[(i-1)&1][j])%Mod; if (j-min(j,cnt[fa[i]])-1>=0) { int y=ss[(i-1)&1][j-min(j,cnt[fa[i]])-1]; f[i&1][j]=(f[i&1][j]-ss[(i-1)&1][j-min(j,cnt[fa[i]])-1])%Mod; } ss[i&1][j]=(ss[i&1][j-1]+f[i&1][j])%Mod; } for (int j=sc[i]+1;j<=100000;++j) ss[i&1][j]=ss[i&1][j-1]; } for (int i=s;i<=b;++i) ans=(ans+f[n&1][i])%Mod; printf("%d\n",ans); }
总结
①使用滚动数组的时候每一次要将当前的一维清0。②前缀和优化要注意:后面全是0的部分要全部赋为最后一个有值的数。否则就会减出负数来。
相关文章推荐
- Bzoj[2023/1630]: [Usaco2005 Nov]Ant Counting 数蚂蚁 DP+滚动数组
- 【bzoj2023/1630】[Usaco2005 Nov]Ant Counting 数蚂蚁 (DP+前缀和+滚动数组)
- 【bzoj2023/1630】[Usaco2005 Nov]Ant Counting 数蚂蚁 dp
- BZOJ 2023: [Usaco2005 Nov]Ant Counting 数蚂蚁——DP
- bzoj 1630 && 2023: [Usaco2005 Nov]Ant Counting 数蚂蚁(有重复元素的组合数)
- BZOJ2023/1630: [Usaco2005 Nov]Ant Counting 数蚂蚁
- bzoj2023【Usaco2005 Nov】Ant Counting 数蚂蚁
- 1630/2023: [Usaco2005 Nov]Ant Counting 数蚂蚁
- BZOJ2023: [Usaco2005 Nov]Ant Counting 数蚂蚁
- 2023: [Usaco2005 Nov]Ant Counting 数蚂蚁
- [bzoj1742][Usaco2005 nov][DP]Grazing on the Run 边跑边吃草
- bzoj 1630: [Usaco2007 Demo]Ant Counting【dp】
- BZOJ 1694 & 1742 [Usaco 2005 nov] 区间DP 解题报告
- BZOJ 3384: [Usaco2004 Nov]Apple Catching 接苹果/BZOJ 1750: [Usaco2005 qua]Apple Catching dp
- BZOJ 1630/2023 Ant Counting 数蚂蚁
- 【BZOJ1630/2023】[Usaco2007 Demo]Ant Counting DP
- 【BZOJ1742】[Usaco2005 nov]Grazing on the Run 边跑边吃草【区间DP】
- bzoj1630/2023 [Usaco2007 Demo]Ant Counting
- bzoj 1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草【区间dp】
- [BZOJ1630]=[BZOJ2023][Usaco2007 Demo]Ant Counting