#189 stat(动态规划)
生活随笔
收集整理的這篇文章主要介紹了
#189 stat(动态规划)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
容易想到固定第一個排列為1~n,算出答案后乘上n!即可,但這樣就離正解走遠了。
考慮排列dp的一般套路,將數從大到小加入排列,這樣每個位置第一次填數時(不管是第一個還是第二個排列)其貢獻就確定了。
顯然當前兩個排列有用的信息僅僅是兩個排列都填了、僅第一個排列填了、僅第二個排列填了、兩個排列都沒填的位置數量。并且注意到僅第一個排列填了和僅第二個排列填了的位置數量是相等的,同時dp過程中也知道當前填了多少個數,所以dp時只要記錄兩個排列都填了的位置數量即可。
于是設f[i][j][k]為填到i時,有j個位置兩個排列都填了,當前貢獻之和為k時的方案數,瞎轉移即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 72 #define P 1000000007 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() {int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f; } int n,m,f[N][N][N*N]; void inc(int &x,int y){x+=y;if (x>=P) x-=P;} int C(int n,int m){return 1ll*n*(n-1)/2%P;} int main() {freopen("stat.in","r",stdin);freopen("stat.out","w",stdout);n=read(),m=read();f[n+1][0][0]=1;for (int i=n+1;i>1;i--){for (int x=0;x<=n+1-i;x++){int y=n+1-i-x,z=n-x-y*2;if (y>=0&&z>=0)for (int k=0;k<=n*n;k++)if (f[i][x][k]){if (z>=2) inc(f[i-1][x][k+(i-1)*2],1ll*f[i][x][k]*z%P*(z-1)%P);if (z>=1) inc(f[i-1][x+1][k+(i-1)],2ll*f[i][x][k]*z%P*y%P);if (z>=1) inc(f[i-1][x+1][k+(i-1)],1ll*f[i][x][k]*z%P);if (y>=1) inc(f[i-1][x+2][k],1ll*f[i][x][k]*y%P*y%P);}}}int ans=0;for (int i=m;i<=n*n;i++) inc(ans,f[1][n][i]);cout<<ans;return 0; }轉載于:https://www.cnblogs.com/Gloid/p/10366619.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的#189 stat(动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件定义的数据中心已经来临
- 下一篇: 如何脱离SDK,使用DW5.5和phon