[关闭]
@994495jj 2017-09-04T06:45:11.000000Z 字数 1363 阅读 829

cf 840C On the Bench(相邻数乘积不能是平方数)

201709 (ACM)动态规划----计数


  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define fi first
  4. #define se second
  5. #define pb push_back
  6. #define sz(a) (int)a.size()
  7. #define mp make_pair
  8. #define rep(i, a, b) for(int i=(a); i<(b); i++)
  9. #define de(a) cout<<#a<<" = "<<a<<endl;
  10. typedef long long ll;
  11. typedef pair<int, int> pii;
  12. typedef vector<int> vi;
  13. //--------
  14. const int mod=1e9+7;
  15. const int N=303;
  16. bool vis[N];
  17. int cb,cc;
  18. int a[N],b[N];
  19. ll jc[N],c[N][N],f[N][N];
  20. vector<int> G[N];
  21. bool che(ll x,ll y) {
  22. ll t=sqrt(x*y);
  23. return t*t==x*y;
  24. }
  25. void dfs(int u) {
  26. if(vis[u]) return ;
  27. ++cc;
  28. vis[u]=1;
  29. rep(i,0,sz(G[u])) dfs(G[u][i]);
  30. }
  31. void init() {
  32. jc[0]=1;
  33. rep(i,1,N) jc[i]=jc[i-1]*i%mod;
  34. rep(i,0,N) c[i][0]=c[i][i]=1;
  35. rep(i,0,N) {
  36. rep(j,1,i) {
  37. c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
  38. }
  39. }
  40. }
  41. void upd(ll &a, ll b) {
  42. a+=b;
  43. if(a>=mod) a-=mod;
  44. }
  45. int main() {
  46. ///
  47. int n;scanf("%d",&n);
  48. ///init
  49. init();
  50. ///read
  51. rep(i,1,n+1) scanf("%d",a+i);
  52. ///get b
  53. rep(i,1,n+1) {
  54. rep(j,i+1,n+1) {
  55. if(che(a[i],a[j])) {
  56. G[i].pb(j);
  57. G[j].pb(i);
  58. }
  59. }
  60. }
  61. rep(i,1,n+1) if(!vis[i]) {
  62. cc=0;
  63. dfs(i);
  64. b[++cb]=cc;
  65. }
  66. ///solve
  67. int tot=0;
  68. f[0][0]=1;
  69. rep(i,1,cb+1) {
  70. rep(j,0,tot+1) {
  71. rep(k,1,min(b[i],tot+1)+1) {
  72. rep(d,0,min(j+1,k+1)) {
  73. upd(f[i][j-d+b[i]-k],f[i-1][j]*c[b[i]-1][k-1]%mod*c[j][d]%mod*c[tot+1-j][k-d]%mod);
  74. }
  75. }
  76. }
  77. tot+=b[i];
  78. }
  79. ll ans=f[cb][0];
  80. rep(i,1,cb+1) ans=ans*jc[b[i]]%mod;
  81. printf("%lld\n",ans);
  82. return 0;
  83. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注