日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF1237F Balanced Domino Placements(dp+组合计数)

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF1237F Balanced Domino Placements(dp+组合计数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CF1237F Balanced Domino Placements

  • problem
  • solution
  • code

problem

題目鏈接

solution

骨牌橫著放會占用一行兩列,骨牌豎著放會占用兩行一列。

問題可以抽象為:每次可以選擇連續的兩行放 AAA,或選一行放 BBB;每次可以選一列放 BBB ,或選連續的兩列放 AAA

且最后行的 AAA 數量等于列的 BBB 數量,列的 AAA 數量等于行的 BBB 數量。【多米諾骨牌大小的匹配】

這樣一個放物品的過程會對應原來很多個多米諾骨牌擺放的方案,因為行列之間 A,BA,BA,B 配對的方案不只一種,任意一種配對方案對應一種不同的擺放方案。

行列之間的 A,BA,BA,B 的擺放是不影響的,只有數量相等的要求。

假設選了 xxxAAAyyyBBB,則方案數為 x!y!x!y!x!y!

由于行列互不影響,所以分開求解,最后利用乘法原理計算即可。下面以行為例。

dpi,j,k:dp_{i,j,k}:dpi,j,k?: 考慮前 iii 行,放了 jjjAAAkkkBBB 的方案數。

暴力的狀態都是 n3n^3n3 的,考慮優化。
實際上,BBB 的性質是只占用一行,只要知道剩下的空位,我們就能計算 BBB 的方案數。

改寫 dpi,j:dp_{i,j}:dpi,j?:iii 行放了 jjjAAA ,還沒有放 BBB 的方案數。

那么最后可以放 BBB 的空位為 cnt?2?jcnt-2*jcnt?2?jcnt:cnt:cnt: 去除掉題目所給多米諾骨牌占用的行后剩下的行數,如果要選 kkkBBB,則可以 O(1)O(1)O(1) 計算方案數為:(cnt?2?jk)\binom{cnt-2*j}{k}(kcnt?2?j?)

最后合并需要枚舉行選了多少個 AAA 和多少個 BBB,枚舉總時間也是 O(n2)O(n^2)O(n2) 的。

所以本題最終的時間復雜度為:O(n2)O(n^2)O(n2)

code

#include <cstdio> #define int long long #define mod 998244353 #define maxn 3605 int n, m, k, cnt_c, cnt_r; int fac[maxn]; bool row[maxn], col[maxn]; int c[maxn][maxn], f[maxn][maxn], g[maxn][maxn];signed main() {scanf( "%lld %lld %lld", &n, &m, &k );cnt_r = n, cnt_c = m;for( int i = 1, X1, Y1, X2, Y2;i <= k;i ++ ) {scanf( "%lld %lld %lld %lld", &X1, &Y1, &X2, &Y2 );row[X1] = row[X2] = col[Y1] = col[Y2] = 1;cnt_r --, cnt_c --;if( X1 ^ X2 ) cnt_r --;else cnt_c --;}fac[0] = f[0][0] = g[0][0] = c[0][0] = 1;for( int i = 1;i < maxn;i ++ ) fac[i] = fac[i - 1] * i % mod;for( int i = 1;i < maxn;i ++ ) {c[i][0] = c[i][i] = 1;for( int j = 1;j < i;j ++ )c[i][j] = ( c[i - 1][j] + c[i - 1][j - 1] ) % mod;}for( int i = 1;i <= n;i ++ )for( int j = 0;j <= i / 2;j ++ ) {f[i][j] = f[i - 1][j];if( i >= 2 and j and ! row[i] and ! row[i - 1] ) f[i][j] = ( f[i][j] + f[i - 2][j - 1] ) % mod;}for( int i = 1;i <= m;i ++ )for( int j = 0;j <= i / 2;j ++ ) {g[i][j] = g[i - 1][j];if( i >= 2 and j and ! col[i] and ! col[i - 1] ) g[i][j] = ( g[i][j] + g[i - 2][j - 1] ) % mod;}int ans = 0;for( int i = 0;i <= cnt_r / 2;i ++ )for( int j = 0;j <= cnt_c / 2;j ++ )if( i * 2 + j <= cnt_r and i + j * 2 <= cnt_c )ans = ( ans + f[n][i] * g[m][j] % mod * c[cnt_r - 2 * i][j] % mod * c[cnt_c - 2 * j][i] % mod * fac[i] % mod * fac[j] ) % mod;printf( "%lld\n", ans );return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的CF1237F Balanced Domino Placements(dp+组合计数)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。