- P4163 [SCOI2007]排列
- 状态压缩 二进制0 1代表,每一位选择的情况,通过位运算进行前继后继状态的转移,最后去重即可。
-
#include<bits/stdc++.h> #define maxn 1<<12 #define ll long long using namespace std; ll n,m,dp[maxn+1][1234],temp; ll fac[15],num[15],x,y,z,t; string str; int main() { ios::sync_with_stdio(false); cin>>t; while(t--) { memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); cin>>str>>m; n=str.size(); dp[0][0]=fac[0]=1; for(int i=0; i<n; i++) { num[str[i]-'0']++; fac[i+1]=fac[i]*(i+1); } ll tot=1<<n; for(int i=0; i<tot; i++) for(int k=0; k<m; k++) { if(!dp[i][k])continue; for(int j=0; j<n; j++) { x=str[j]-'0'; if((1<<j)&i)continue; y=((1<<j)|i); z=(k*10+x)%m; dp[y][z]+=dp[i][k]; } } temp=1; for(int i=0; i<10; i++) temp*=fac[num[i]]; dp[tot-1][0]/=temp; printf("%lld\n",dp[tot-1][0]); } return 0; }
P4163 [SCOI2007]排列-状压DP
最新推荐文章于 2022-06-17 10:40:03 发布