B3902 [NICA #3] 数计组数 题解
简单计数背包 DP。
令
计算过程可以借助快速幂实现。std::lower_bound 预处理。
放代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int p=1e9+7;
int qpow(int a,int b){
int r=1;
while(b){
if(b&1)r=r%p*a%p;
a=a%p*a%p,b>>=1;
}
return r;
} // 快速幂
main(){
ios::sync_with_stdio(false);
int n,m; cin>>n>>m;
vector<int> b(m),e(n+1),c(n+1),f(n+1);
for(auto &i:b)if(cin>>i;i<=n)e[i]=1;
for(int i=1;i<=n;i++)
c[i]=m-(lower_bound(b.begin(),b.end(),i)-b.begin());
// 二分预处理
for(int i=f[0]=1;i<=n;i++)
for(int j=0;j<i;j++)
if(e[i-j])(f[i]+=f[j]*(qpow(c[i-j],i-j)-qpow(c[i-j]-1,i-j)+p)%p)%=p;
// 进行转移
cout<<f[n]<<endl;
return 0;
}