题目链接

题面:

题意:
有 nnn 种颜色的石子,第 iii 种颜色的石子有 aia_iai​ 个。
我现在要从里面选出若干个石子排成一排,问有多少种不同的序列。

两个序列不同当且仅当长度不同或者至少有某个位置的对应颜色不同。

题解:
考虑 dp[i][j]dp[i][j]dp[i][j],表示我考虑的前 iii 种颜色的石子,现在构成的长度为 jjj 的序列的不同排列的方案数。

转移方程显然 dp[i][j]=∑k=0min(sum[i],j)dp[i−1][j−k]∗Cjkdp[i][j]=\sum\limits_{k=0}^{min(sum[i],j)}dp[i-1][j-k]*C_j^kdp[i][j]=k=0∑min(sum[i],j)​dp[i−1][j−k]∗Cjk​

虽然这样的理论时间复杂度大概是 O(T∗1e8)O(T*1e8)O(T∗1e8),TTT 为数据的组数。

但是能过。

#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
//#include<unordered_map>
#include<set>
//#include<unordered_set>
namespace onlyzhao
{#define ui unsigned int#define ll long long#define llu unsigned ll#define ld long double#define pr make_pair#define pb push_back#define lc (cnt<<1)#define rc (cnt<<1|1)#define len(x)  (t[(x)].r-t[(x)].l+1)#define tmid ((l+r)>>1)#define fhead(x) for(int i=head[(x)];i;i=nt[i])#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define one(n) for(int i=1;i<=(n);i++)#define rone(n) for(int i=(n);i>=1;i--)#define fone(i,x,n) for(int i=(x);i<=(n);i++)#define frone(i,n,x) for(int i=(n);i>=(x);i--)#define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))#define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))#define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define fvc(vc) for(int i=0;i<vc.size();i++)#define frvc(vc) for(int i=vc.size()-1;i>=0;i--)#define forvc(i,vc) for(int i=0;i<vc.size();i++)#define forrvc(i,vc) for(int i=vc.size()-1;i>=0;i--)#define cls(a) memset(a,0,sizeof(a))#define cls1(a) memset(a,-1,sizeof(a))#define clsmax(a) memset(a,0x3f,sizeof(a))#define clsmin(a) memset(a,0x80,sizeof(a))#define cln(a,num) memset(a,0,sizeof(a[0])*num)#define cln1(a,num) memset(a,-1,sizeof(a[0])*num)#define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)#define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)#define sc(x) scanf("%d",&x)#define sc2(x,y) scanf("%d%d",&x,&y)#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define scl(x) scanf("%lld",&x)#define scl2(x,y) scanf("%lld%lld",&x,&y)#define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)#define scf(x) scanf("%lf",&x)#define scf2(x,y) scanf("%lf%lf",&x,&y)#define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)#define scs(x) scanf("%s",x+1)#define scs0(x) scanf("%s",x)#define scline(x) scanf("%[^\n]%*c",x+1)#define scline0(x) scanf("%[^\n]%*c",x)#define pcc(x) putchar(x)#define pc(x) printf("%d\n",x)#define pc2(x,y) printf("%d %d\n",x,y)#define pc3(x,y,z) printf("%d %d %d\n",x,y,z)#define pck(x) printf("%d ",x)#define pcl(x) printf("%lld\n",x)#define pcl2(x,y) printf("%lld %lld\n",x,y)#define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)#define pclk(x) printf("%lld ",x)#define pcf2(x) printf("%.2f\n",x)#define pcf6(x) printf("%.6f\n",x)#define pcf8(x) printf("%.8f\n",x)#define pcs(x) printf("%s\n",x+1)#define pcs0(x) printf("%s\n",x)#define pcline(x) printf("%d**********\n",x)#define casett int tt;sc(tt);int pp=0;while(tt--)char buffer[100001],*S,*T;inline char Get_Char(){if (S==T){T=(S=buffer)+fread(buffer,1,100001,stdin);if (S==T) return EOF;}return *S++;}inline ll read(){char c;ll re=0;for(c=Get_Char();c<'0'||c>'9';c=Get_Char());while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();return re;}
};
using namespace onlyzhao;
using namespace std;const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=40100;
const int maxm=100100;
const int up=1e9;
const int maxp=1010;int fac[maxn],inv[maxn];
int pc[maxn];ll mypow(ll a,ll b)
{ll ans=1;while(b){if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;
}void init(void)
{fac[0]=1;for(int i=1;i<maxn;i++)fac[i]=1ll*fac[i-1]*i%mod;inv[maxn-1]=mypow(fac[maxn-1],mod-2);for(int i=maxn-2;i>=0;i--)inv[i]=1ll*inv[i+1]*(i+1)%mod;
}int C(int n,int m)
{return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
int dp[110][10010];int main(void)
{int n;int pp=0;init();while(scanf("%d",&n)!=EOF){int sum=0;for(int i=1;i<=n;i++)scanf("%d",&pc[i]);memset(dp,0,sizeof(dp));dp[0][0]=1;for(int i=1;i<=n;i++){sum+=pc[i];for(int j=0;j<=sum;j++){dp[i][j]=0;for(int k=0;k<=pc[i]&&k<=j;k++)dp[i][j]=(dp[i][j]+1ll*dp[i-1][j-k]*C(j,k))%mod;}}int ans=0;for(int i=1;i<=sum;i++)ans=(ans+dp[n][i])%mod;printf("Case %d: %d\n",++pp,ans);}return 0;
}

其实这个题,在写的时候用的生成函数写的,当时看过的不多,就以为是个数论题。
但是一看模数是 1e9+71e9+71e9+7 ,感觉也不像是用生成函数做。但是也没往 dpdpdp 上面想。
如果是 马哥 或者 冰哥 开了这个题的话,肯定就是秒过。

其实生成函数也能过,原 OJOJOJ 开了 15s15s15s 时限,跑了大约 5s5s5s。

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
//#include<unordered_map>
#include<set>
//#include<unordered_set>
namespace onlyzhao
{#define ui unsigned int#define ll long long#define llu unsigned ll#define ld long double#define pr make_pair#define pb push_back#define lc (cnt<<1)#define rc (cnt<<1|1)#define len(x)  (t[(x)].r-t[(x)].l+1)#define tmid ((l+r)>>1)#define fhead(x) for(int i=head[(x)];i;i=nt[i])#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)>(y)?(y):(x))#define one(n) for(int i=1;i<=(n);i++)#define rone(n) for(int i=(n);i>=1;i--)#define fone(i,x,n) for(int i=(x);i<=(n);i++)#define frone(i,n,x) for(int i=(n);i>=(x);i--)#define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))#define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))#define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)#define fvc(vc) for(int i=0;i<vc.size();i++)#define frvc(vc) for(int i=vc.size()-1;i>=0;i--)#define forvc(i,vc) for(int i=0;i<vc.size();i++)#define forrvc(i,vc) for(int i=vc.size()-1;i>=0;i--)#define cls(a) memset(a,0,sizeof(a))#define cls1(a) memset(a,-1,sizeof(a))#define clsmax(a) memset(a,0x3f,sizeof(a))#define clsmin(a) memset(a,0x80,sizeof(a))#define cln(a,num) memset(a,0,sizeof(a[0])*num)#define cln1(a,num) memset(a,-1,sizeof(a[0])*num)#define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)#define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)#define sc(x) scanf("%d",&x)#define sc2(x,y) scanf("%d%d",&x,&y)#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define scl(x) scanf("%lld",&x)#define scl2(x,y) scanf("%lld%lld",&x,&y)#define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)#define scf(x) scanf("%lf",&x)#define scf2(x,y) scanf("%lf%lf",&x,&y)#define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)#define scs(x) scanf("%s",x+1)#define scs0(x) scanf("%s",x)#define scline(x) scanf("%[^\n]%*c",x+1)#define scline0(x) scanf("%[^\n]%*c",x)#define pcc(x) putchar(x)#define pc(x) printf("%d\n",x)#define pc2(x,y) printf("%d %d\n",x,y)#define pc3(x,y,z) printf("%d %d %d\n",x,y,z)#define pck(x) printf("%d ",x)#define pcl(x) printf("%lld\n",x)#define pcl2(x,y) printf("%lld %lld\n",x,y)#define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)#define pclk(x) printf("%lld ",x)#define pcf2(x) printf("%.2f\n",x)#define pcf6(x) printf("%.6f\n",x)#define pcf8(x) printf("%.8f\n",x)#define pcs(x) printf("%s\n",x+1)#define pcs0(x) printf("%s\n",x)#define pcline(x) printf("%d**********\n",x)#define casett int tt;sc(tt);int pp=0;while(tt--)char buffer[100001],*S,*T;inline char Get_Char(){if (S==T){T=(S=buffer)+fread(buffer,1,100001,stdin);if (S==T) return EOF;}return *S++;}inline ll read(){char c;ll re=0;for(c=Get_Char();c<'0'||c>'9';c=Get_Char());while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();return re;}
};
using namespace onlyzhao;
using namespace std;const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e18;
const int mod=1e9+7;
const double eps=1e-8;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=40100;
const int maxm=100100;
const int up=1e9;
const int maxp=1010;const int p=mod;
const int g=3;
int fi[maxn];
int n,m;
int aa[maxn],bb[maxn];
int pc[maxn];
ll fac[maxn],inv[maxn];ll mypow(ll a,ll b,ll p=mod)
{if(b<0) return mypow(mypow(a,p-2,p),-b,p);a%=p;ll ans=1;while(b){if(b&1) ans=ans*a%p;a=a*a%p;b>>=1;}return ans%p;
}void init(void)
{fac[0]=1;for(int i=1;i<maxn;i++)fac[i]=fac[i-1]*i%mod;inv[maxn-1]=mypow(fac[maxn-1],mod-2);for(int i=maxn-2;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
}struct Complex
{double x,y;Complex(double xx=0.0,double yy=0.0){x=xx,y=yy;}Complex operator - (const Complex &b) const{return Complex(x-b.x,y-b.y);}Complex operator + (const Complex &b) const{return Complex(x+b.x,y+b.y);}Complex operator * (const Complex &b) const{return Complex(x*b.x-y*b.y,x*b.y+y*b.x);}
};
int ans[maxn];
Complex a1[maxn],b1[maxn],a2[maxn],b2[maxn],ww[maxn],a[maxn];void fft(Complex *x,int len,int f)
{for(int i=0;i<len;i++)if(i<fi[i]) swap(x[i],x[fi[i]]);for(int i=1;i<len;i<<=1){for(int r=i<<1,j=0;j<len;j+=r){for(int k=0;k<i;k++){Complex w=ww[len/i*k];w.y*=f;Complex xx=x[j+k],yy=w*x[j+i+k];x[j+k]=xx+yy;x[j+i+k]=xx-yy;}}}if(f==-1)for(int i=0;i<len;i++)x[i].x/=len;
}void get(Complex *x,Complex *y,int len,int pm)
{for(int i=0;i<len;i++) a[i]=x[i]*y[i];fft(a,len,-1);for(int i=0;i<len;i++)ans[i]=(ans[i]+(ll)(a[i].x+0.5)%p*1ll*pm)%p;
}void get(int n,int m,int *a,int *b,int p=mod)
{int len=1,cnt=0;while(len<=n+m) len<<=1,cnt++;for(int i=0;i<len;i++){fi[i]=((fi[i>>1]>>1)|((i&1)<<(cnt-1)));ww[i]=Complex(cos(pi/len*i),sin(pi/len*i));}int pm=32768;int x;for(int i=0;i<=n;i++){x=a[i];a1[i].x=x/pm,b1[i].x=x%pm;a1[i].y=0,b1[i].y=0;}for(int i=n+1;i<=len;i++)a1[i].x=a1[i].y=b1[i].x=b1[i].y=0;for(int i=0;i<=m;i++){x=b[i];a2[i].x=x/pm,b2[i].x=x%pm;a2[i].y=0,b2[i].y=0;}for(int i=m+1;i<=len;i++)a2[i].x=a2[i].y=b2[i].x=b2[i].y=0;fft(a1,len,1);fft(b1,len,1);fft(a2,len,1);fft(b2,len,1);get(a1,a2,len,1ll*pm*pm%p);get(a1,b2,len,pm%p);get(a2,b1,len,pm%p);get(b1,b2,len,1);for(int i=0;i<=len;i++)a[i]=ans[i],ans[i]=0;}int main(void)
{init();int n;int pp=0;while(scanf("%d",&n)!=EOF){int sum=0;for(int i=1;i<=n;i++){scanf("%d",&pc[i]);}for(int i=1;i<=n;i++){if(i==1){for(int j=0;j<=pc[i];j++)aa[j]=inv[j];sum=pc[i];}else{for(int j=0;j<=pc[i];j++)bb[j]=inv[j];get(sum,pc[i],aa,bb);sum+=pc[i];}}ll res=0;for(int i=1;i<=sum;i++)res=(res+fac[i]*aa[i])%mod;printf("Case %d: %lld\n",++pp,res);}return 0;}

HDU--4248、A Famous Stone Collector (计数类dp)相关推荐

  1. HDU - 4248 A Famous Stone Collector(dp+组合数学)

    题目链接:点击查看 题目大意:给出 n 种不同种类的石子,每种石子的个数是 a[ i ] 个,记 sum 为石子的总数,问用 k ∈ [ 1 ,  sum ] 个石子组成的不同排列组合有多少种 题目分 ...

  2. 数数题(计数类 DP)做题记录

    数数题(计数类 DP)做题记录 CF1657E Star MST 我们称张无向完全图是美丽的当且仅当:所有和 \(1\) 相连的边的边权之和等于这张完全图的最小生成树的边权之和. 完全图点数为 \(n ...

  3. Acwing900. 整数划分[计数类dp]:完全背包解法

    文章目录 题目分析 完全背包解法 题目链接 题目分析 完全背包解法 请复习完全背包模板完全背包dp优化内有完整标准完全背包的推导过程 状态表示: f[i][j]f[i] [j]f[i][j] 表示从 ...

  4. CF559C-Gerald and Giant Chess【计数类dp】

    正题 上不了Codeforces,就用洛谷了 评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=CF559C 题目大意 H∗WH ...

  5. POJ - 1737 Connected Graph,Java(计数类DP)

    POJ - 1737 Connected Graph C++高精太难写了,直接用Java的大整数会方便一点 常规方法 import java.io.*; import java.math.BigInt ...

  6. 整数划分(计数类DP)

    题目 一个正整数 n 可以表示成若干个正整数之和,形如:n=n1+n2+-+nk,其中 n1≥n2≥-≥nk,k≥1. 我们将这样的一种表示称为正整数 n 的一种划分. 现在给定一个正整数 n,请你求 ...

  7. UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)

    UOJ #214 合唱队形 (概率期望计数.DP.Min-Max容斥) 9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/ ...

  8. 第22次CSP认证 第4题 校门外的树(3种方法,非常详细)(类dp+数学)

    链接: 官网: http://118.190.20.162/view.page?gpid=T125 Acwing:https://www.acwing.com/problem/content/desc ...

  9. hdu 6026 Deleting Edges(最短路计数)

    题目链接:hdu 6026 Deleting Edges 题意: 给你n个点,和一个邻接矩阵,非0表示有边,0表示没边. 现在让你删一些边,构成一棵树,使得每个点到0这个点的距离为没删边之前的最短路. ...

最新文章

  1. 喷涂机器人保养应该注意的七个事项
  2. vuecli3的svgicon_vue-cli3引入svg图标全过程以及遇到的坑
  3. 华为ax3怎么接光纤sc接口_视频监控工程中使用光纤光缆注意事项有哪些?
  4. 为什么深度学习几乎成了计算机视觉研究的标配?
  5. Spring MVC 向前台页面传值-ModelAndView
  6. Java基础知识——Java集合详解
  7. 关于Tensorflow安装opencv和pygame
  8. Ubuntu在线体验
  9. 用类,求三个数的最大数
  10. linux划分5t硬盘,关于磁盘分区(以linux系统为例)
  11. Teleport Ultra 抓包工具
  12. 2019 ACM/ICPC 南昌站 G,拉格朗日插值
  13. mvc5 + ef6 + autofac搭建项目(三)
  14. Codeforeces Round #226 (Div. 2) E---Bear in the Field(矩阵快速幂)
  15. 3.10 触发字检测
  16. IPhone IPad 利用cocos2d开发游戏问题
  17. C-Free 5.0注册码分享
  18. IntelliJ IDEA 创建 Vue工程
  19. 多目标跟踪综述-Multiple Object Tracking: A Literature Review
  20. Oracle 数据库插入时间字段

热门文章

  1. 阿里、京东、鹅厂、并夕夕、美团BATJ面试之Redis+多线程+JVM+微服务...
  2. 我爱记单词测试报告兼功能展示
  3. python编写人口预测图_Python可视化神器——pyecharts(实例之人口地图)
  4. 几千行代码就能搞定,你为什么要写几万行?
  5. 计算机硬件的漏洞,震惊了硬件圈子的CPU漏洞,到底是个什么鬼?
  6. 985太卷?这些被戏称为“984.5”的宝藏院校,行业认可度极高!
  7. 真的很好的矿石收音机
  8. 使用VFW开发视频采集软件
  9. 操作系统笔记——进程管理
  10. 今年疫情圣诞老人很忙,所以今年轮到我来给你们送圣诞惊喜啦~