zoukankan      html  css  js  c++  java
  • N球M盒问题 & Password Attacker google code jam

      第一个题目本质是个动归dp问题。但是分析dp的方程使用了组合数学中的N求M盒问题。

    先来看下N球M盒的经典问题。

    给定N个相同的球,放入M个不同的盒子中,要求每个盒子必须非空,求组合数。

    假设Xi为第i个盒子中的放入的小球数,则方程

    X1+X2+X3+...+Xm=N,

    其实抽象成数学问题,就是求这个M元1次方程的正整数解的组数。

    插板法分析:

    N个小球排成一行,插入M-1个板,只能在小球中间插,而且板与板之间必须有球

    分析到这里,聪明的大家肯定一看就知道是个N-1个空隙选M-1个来放入板,Cm-1,n-1.

    有了上面的分析方法后,我们可以接着来分析原题。

    dp[i][j]可以先考虑dp[i-1][k],

    那么还剩下j-k个相同的元素待插入,把j-k相同的球分成k个不同的堆,每堆可以为空。

    为了转化成堆至少有一个球的情形,我们每个堆放入一个球,现在又可以变成了插板问题。最后插板得到的组合,每个减去1就是了

    所以:最后动归的公式就是

    dp(i,j)=sum( dp(i-1,k)C(j,k))

    k 是 i-1 ~ j-1

    调试的过程中一定用longlong来存储

    typedef int64 long long 

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<iomanip>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<string>
      8 #include<sstream>
      9 #include<vector>
     10 #include<map>
     11 #include<set>
     12 #include<bitset>
     13 #include<algorithm>
     14 #include<cassert>
     15 #include<ctime>
     16 #include<queue>
     17 using namespace std;
     18 
     19 #define REP(i,n) for(int i = 0; i < (int)n; i++)
     20 #define FOR(i,n,m) for(int i = (int)n; i <= (int)m; i++)
     21 #define FOD(i,n,m) for(int i = (int)n; i >= (int)m; i--)
     22 #define EACH(i,v) for(decltype((v).begin()) i = (v).begin(); i != (v).end(); i++)
     23 
     24 typedef long long i64;
     25 typedef pair<int, int> PI;
     26 
     27 #define sz(v) ((i64)(v).size())
     28 #define all(v) (v).begin(),(v).end()
     29 #define bit(n) (1LL<<(i64)(n))
     30 
     31 #define PB push_back
     32 #define MP make_pair
     33 #define X first
     34 #define Y second
     35 template<class T> void fmax(T &a, const T &b) { if (a < b) a = b; }
     36 template<class T> void fmin(T &a, const T &b) { if (a > b) a = b; }
     37 template<class T> T sqr(const T &a) { return a * a; }
     38 
     39 long long M=1000000007LL;
     40 
     41 long long C[101][101];
     42 long long  dp[101][101];
     43 
     44 void composition(){
     45     FOR(i,0,100){
     46         C[i][i]=1;
     47         C[i][0]=1;
     48     }
     49 
     50     FOR(i,2,100){
     51         FOR(j,1,i-1){
     52             C[i][j]=C[i-1][j]+C[i-1][j-1];
     53         }
     54     }
     55 }
     56 
     57 void getCombination() {
     58     int n = 105;
     59     for (int i = 1; i <= n; i++)
     60         C[i][0] = C[i][i] = 1LL;
     61 
     62     for (int i = 2; i <= n; i++)
     63     for (int j = 1; j <= i; j++)
     64         C[i][j] = (C[i-1][j-1] % M + C[i-1][j] % M) % M;
     65 }
     66 
     67 long long  solve(int m,int n){
     68     /*
     69     memset(dp,0,sizeof(dp));
     70     FOR(i,1,n)
     71         dp[1][i]=1;
     72     FOR(i,2,n)
     73         dp[i][i]=(dp[i-1][i-1] * (long long)i ) %M;
     74 
     75     FOR(i,2,m){
     76         FOR(j,i+1,n){
     77             FOR(k,i-1,j-1){
     78                 //dp[i][j]=(dp[i][j]+(dp[i-1][k]*C[j][k])%M)%M;
     79                 dp[i][j] = (dp[i][j] + (C[j][k] * dp[i-1][k]) % M) % M;
     80             }
     81         }
     82     }
     83     */
     84     memset(dp, 0LL, sizeof(dp));
     85         for (int i = 1; i <= n; i++)    dp[1][i] = 1;
     86         for (int i = 2; i <= n; i++)    dp[i][i] = (dp[i-1][i-1] * (long long)i) % M;
     87         
     88         for (int i = 2; i <= m; i++)
     89         for (int j = i+1; j <= n; j++)
     90         for (int k = i-1; k <= j-1; k++)
     91             dp[i][j] = (dp[i][j] + (C[j][k] * dp[i-1][k]) % M) % M;
     92     return dp[m][n];
     93 }
     94 
     95 int main(){
     96     freopen("input.txt","r",stdin);
     97 //    freopen("out.txt","w",stdout);
     98     int M,N,T;
     99     //composition();
    100     getCombination();
    101     cin>>T;
    102     int counter=1;
    103     while(T--){
    104         cin>>M>>N;
    105         cout<<"Case #"<<counter++<<": "<<solve(M,N)<<endl;
    106         
    107     }
    108     return 0;
    109 }
    View Code

    最后代码奉上

  • 相关阅读:
    模块的初始
    requests模块的高级用法
    爬虫数据解析方式
    2th
    0
    ..
    .

    1th-绪论
    Py2x & Py3x版本的区别
  • 原文地址:https://www.cnblogs.com/bianzeming/p/4020599.html
Copyright © 2011-2022 走看看