Concise and clear CodeForces - 991F(dfs 有重复元素的全排列)
就是有重复元素的全排列
#include <bits/stdc++.h> #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long LL; const int maxn = 10010, INF = 0x7fffffff; char str[maxn]; int vis[maxn], v[maxn]; LL num[maxn]; LL res = 0; void init() { num[0] = 1; for(int i=1; i<maxn; i++) num[i] = num[i-1] * i; } void dfs(LL x, LL cnt) { if(cnt == 10) { if(x > 0) return; LL ans1 = 1, ans2 = 0, ans3 = 1; for(int i=0; i<=9; i++) { ans2 += v[i]; } LL temp = ans2; ans2 = num[ans2]; for(int i=0; i<=9; i++) ans2 /= num[v[i]]; // cout<< ans2 <<endl; if(v[0]) { ans3 = num[temp-1]; for(int i=0; i<=9; i++) if(i == 0) ans3 /= num[v[i]-1]; else ans3 /= num[v[i]]; ans2 -= ans3; } res += ans2; return; } if(!vis[cnt]) dfs(x, cnt+1); else for(int i=0; i<vis[cnt] && i<=x; i++) { v[cnt] += i; dfs(x-i, cnt+1); v[cnt] -= i; } } int main() { init(); cin>> str; int len = strlen(str); int maxx = -INF; LL sum = 0, ans = 0, flag = 0; for(int i=0; i<len; i++) { if(i != 0) if(str[i] != str[i-1]) flag = 1; vis[str[i]-'0']++; if(vis[str[i]-'0'] == 1) ans++; } if(!flag) { cout<< len <<endl; return 0; } res += num[ans]; if(vis[0]) res -= num[ans-1]; for(int i=0; i<=9; i++) if(vis[i]) sum += vis[i]-1; for(int i=1; i<=sum; i++) { for(int i=0; i<=9; i++) if(vis[i]) v[i] = 1; else v[i] = 0; dfs(i, 0); } cout<< res <<endl; return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。