bzoj 1072 排列perm
题目大意:
给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0)
思路:
早上棒神告诉我一道状压dp
我看了看数据感觉可以next_permutation+map艹过去
结果发现这种时候map太辣鸡T掉了
然后换了set
然后,然后就艹过去了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<set> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 105 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 ll T,k,n,a[11],p,ans; 22 set <ll> s; 23 int main() 24 { 25 T=read(); 26 while(T--) 27 { 28 char ch[11];scanf("%s",ch);k=read(); 29 s.clear(); 30 n=strlen(ch);ans=0; 31 for(int i=0;i<n;i++) a[i]=ch[i]-'0'; 32 sort(a,a+n); 33 do 34 { 35 p=a[0]; 36 for(int i=1;i<n;i++) p=p*10+a[i]; 37 if(p%k==0&&!s.count(p)) {ans++;s.insert(p);} 38 } 39 while(next_permutation(a,a+n)); 40 printf("%d\n",ans); 41 } 42 }
晚上回家觉得自己太菜
还是写一下状压dp
然后就搞了一下
dp i j 表示用了i位(压缩后) 除d余j的方案数
然后就可以愉快的转移了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 13 #define MOD 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 19 while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); 20 return x*f; 21 } 22 int p,dp[1030][1010],n,T,cnt[15],a[15]; 23 int main() 24 { 25 T=read(); 26 while(T--) 27 { 28 memset(dp,0,sizeof(dp)); 29 memset(cnt,0,sizeof(cnt)); 30 char ch[15];scanf("%s",ch);n=strlen(ch),dp[0][0]=1,p=read(); 31 for(int i=0;i<n;i++) a[i]=ch[i]-'0',cnt[a[i]]++; 32 for(int i=0;i<(1<<n);i++) 33 for(int j=0;j<p;j++) 34 for(int k=0;k<n;k++) 35 if(!(i&(1<<k))) dp[i|(1<<k)][(j*10+a[k])%p]+=dp[i][j]; 36 int ans=dp[(1<<n)-1][0]; 37 for(int i=0;i<=9;i++) 38 for(int j=1;j<=cnt[i];j++) ans/=j; 39 printf("%d\n",ans); 40 } 41 }