计数类DP
所谓计数类DP就是常说的统计可行解数目的问题,区别于求解最优解,此类问题需要统计所有满足条件的可行解,而求解最优值的DP问题往往只需要统计子问题时满足不漏的条件即可,但是计数类DP需要满足不重不漏的条件,是约束更高的。
最常见的计数类DP问题就是上楼梯的问题,我们要求解此类问题一个重要的点就是如何划分子问题,然后做到不重不漏,大部分情况下我们想到的方法,同一个解可能会被多次统计,这是不合理的。此类问题也常常与组合数结合到一起,我们可能需要用到数学中组合数的概念,所以如何快速实现组合数,也要掌握好。
对于如何不重不漏地计数,我觉得一个很重要的点就是定序,也即制定一个数据排列的顺序,使得后面的数据不会影响前面的统计结果。
快速求解模余组合数的值
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long jc[200010],jcinv[200010];//存储阶乘和阶乘在模mod下的乘法逆元,利用费马小定理
//快速幂
long long power(long long a,int b){
long long ans=1;
for(;b;b>>=1){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
}
return ans;
}
//求解组合数
long long C(int n,int m){
return jc[n]*jcinv[m]%mod*jcinv[n-m]%mod;
}
int main(){
jc[0]=1;
jcinv[0]=1;
for(int i=1;i<=200000;i++){
jc[i]=jc[i-1]*i%mod;
jcinv[i]=power(jc[i],mod-2);
}
return 0;
}
例题
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int mod=1e9+7