zoukankan      html  css  js  c++  java
  • HDU 5155 Harry And Magic Box dp

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5155

    题意:

    给n*m的零一矩阵,问它的左视图和正视图都为全1的所有情况。

    题解:

    n,m不超过50,所以可以跑O(n^4);

    另dp[i][j]代表前i行(每一行至少放一个,因为这样就可以只考虑列会不会为空就可以了)中有j列不全为0,那么有状态转移方程:

    dp[i][k]+=dp[i-1][j]*C[m-j][k-j]*C[j][t](0<=t<=j)

    C[i][j]表示i个方格中j个为1的所有情况。(组合数,可递推离线处理出来)

    (题外话:原先以为要和TSP一样,要用集合来表示状态,但其实它这里填的位置不连续其实没有影响,因为它等价于连续的情况。)

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 typedef __int64 LL;
     6 
     7 const int maxn = 55;
     8 const int mod = 1e9 + 7;
     9 
    10 int n, m;
    11 LL dp[maxn][maxn];
    12 
    13 LL C[maxn][maxn];
    14 void get_c() {
    15     for (int i = 0; i < maxn; i++) {
    16         C[i][0] = 1;
    17         for (int j = 1; j <= i; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
    18     }
    19 }
    20 
    21 void init() {
    22     memset(dp,0,sizeof(dp));
    23 }
    24 
    25 int main() {
    26     get_c();
    27     while (scanf("%d%d", &n, &m) == 2 && n) {
    28         init();
    29         for (int j = 1; j <= m; j++) dp[1][j] = C[m][j];
    30         for (int i = 2; i <= n; i++) {
    31             for (int j = 1; j <= m; j++) {
    32                 for (int k = j; k <= m; k++) {
    33                     for (int t = 0; t <= j; t++) {
    34                         if (k == j&&t == 0) continue;
    35                         dp[i][k] += dp[i - 1][j] * C[m - j][k - j] % mod*C[j][t] % mod;
    36                         dp[i][k] %= mod;
    37                     }
    38                 }
    39             }
    40         }
    41         printf("%lld
    ", dp[n][m]);
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    SCRUM站立会议
    燃尽图
    第一次作业----词频统计
    构建之法读感
    final 评论 II
    final 评论 I
    第十一周PSP
    学期回顾
    第十周PSP
    Gradle学习笔记
  • 原文地址:https://www.cnblogs.com/fenice/p/5451712.html
Copyright © 2011-2022 走看看