zoukankan      html  css  js  c++  java
  • hdu 5155(递推)

    Harry And Magic Box

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 624    Accepted Submission(s): 293


    Problem Description
    One day, Harry got a magical box. The box is made of n*m grids. There are sparking jewel in some grids. But the top and bottom of the box is locked by amazing magic, so Harry can’t see the inside from the top or bottom. However, four sides of the box are transparent, so Harry can see the inside from the four sides. Seeing from the left of the box, Harry finds each row is shining(it means each row has at least one jewel). And seeing from the front of the box, each column is shining(it means each column has at least one jewel). Harry wants to know how many kinds of jewel’s distribution are there in the box.And the answer may be too large, you should output the answer mod 1000000007.
     
    Input
    There are several test cases.
    For each test case,there are two integers n and m indicating the size of the box. 0n,m50.
     
    Output
    For each test case, just output one line that contains an integer indicating the answer.
     
    Sample Input
    1 1 2 2 2 3
     
    Sample Output
    1 7 25
    Hint
    There are 7 possible arrangements for the second test case. They are: 11 11 11 10 11 01 10 11 01 11 01 10 10 01 Assume that a grids is '1' when it contains a jewel otherwise not.
     
    Source
     
    题意:一个n*m的矩阵,里面有一些珠宝,保证从行看过去每一行至少都有一个,从列看过去每列至少会有一个,问总共有多少珠宝摆放的可能方式??
    题解:巧妙地递推.
    假设dp[i][j]是前 i 行 前 j 列满足条件的个数
    如果 dp[i][j-1] 已经满足了前 i 行,j-1 列都满足条件,那么第j行可以从 (1,n)个随意摆放
    dp[i][j] = dp[i][j-1]*(C(i,1)+C(i,2)...+C(i,i)) = dp[i][j-1]*(2^i-1)
    如果 dp[i][j-1] 中有k 行没有放东西,那么
    dp[i][j] = dp[i-k][j-1]*C(i,k)*(C(i-k,0)+C(i-k,1)+C(i-k,2)...+C(i-k,i-k))=dp[i-k][j-1]*C(i,k)*2^(i-k)
    /**
    假设dp[i][j]是前 i 行 前 j 列满足条件的个数
    如果 dp[i][j-1] 已经满足了前 i 行,j-1 列都满足条件,那么第j行可以从 (1,n)个随意摆放
    dp[i][j] = dp[i][j-1]*(C(i,1)+C(i,2)...+C(i,i)) = dp[i][j-1]*(2^i-1)
    如果 dp[i][j-1] 中有k 行没有放东西,那么
    dp[i][j] = dp[i-k][j-1]*C(i,k)*(C(i-k,0)+C(i-k,1)+C(i-k,2)...+C(i-k,i-k))=dp[i-k][j-1]*C(i,k)*2^(i-k)
    */
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include <stdlib.h>
    #include<math.h>
    #include<algorithm>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const LL mod = 1000000007;
    LL c[55][55];
    LL dp[55][55];
    void init(){
        for(int i=1;i<55;i++){
            c[i][0]=c[i][i]=1;
            for(int j=1;j<i;j++){
                c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
            }
        }
    }
    LL pow_mod(LL a,LL n){
        LL ans = 1;
        while(n){
            if(n&1) ans = ans*a%mod;
            a = a*a%mod;
            n>>=1;
        }
        return ans;
    }
    int main()
    {
        init();
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++){
                dp[i][1] = 1;
            }
            for(int i=1;i<=m;i++){
                dp[1][i] = 1;
            }
            for(int i=2;i<=n;i++){
                for(int j=2;j<=m;j++){
                    dp[i][j] = dp[i][j-1]*(pow_mod(2,i)-1)%mod;
                    for(int k=1;k<i;k++){
                        dp[i][j] = (dp[i][j] + dp[i-k][j-1]*c[i][k]%mod*(pow_mod(2,i-k))%mod)%mod;
                    }
                }
            }
            printf("%lld
    ",dp[n][m]);
        }
        return 0;
    }
  • 相关阅读:
    Linux文件系统_每一个的意义
    Linux启动的流程
    Linux
    awk编程
    Junit测试Controller(MockMVC使用),传输@RequestBody数据解决办法
    spring boot get和post请求,以及requestbody为json串时候的处理
    Spring Boot快速入门
    Spring Boot 实用MyBatis做数据库操作
    极简操作无需root隐藏S8导航栏和状态栏
    springboot(三):Spring boot中Redis的使用
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5673947.html
Copyright © 2011-2022 走看看