Advertisement
Guest User

Untitled

a guest
Nov 14th, 2011
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.58 KB | None | 0 0
  1. #pragma comment(linker,"/STACK:300000000")
  2. #define _CRT_SECURE_NO_WARNINGS
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <string>
  7. #include <algorithm>
  8. #include <cmath>
  9. #include <map>
  10. #include <set>
  11. #include <iomanip>
  12. #include <memory.h>
  13. #include <cstdio>
  14. #include <sstream>
  15. #include <deque>
  16. #include <bitset>
  17. #include <numeric>
  18. #include <ctime>
  19. #include <queue>
  20.  
  21. using namespace std;
  22.  
  23. #define show(x) cout << #x << " = " << (x) << endl;
  24. #define fori(i,n) for(int i = 0; i < (n); i++)
  25. #define forn(i,n) for(int i = 1; i <= (n); i++)
  26. #define forab(i,a,b) for(int i = (a); i <= (b); i++)
  27. #define sz(v) ((int)(v).size())
  28. #define all(v) (v).begin(),(v).end()
  29. const double pi = 3.1415926535897932384626433832795;
  30. template<class T> T abs(T &a) { return a >= 0 ? a : -a; };
  31. template<class T> T sqr(T &x) { return x * x; }
  32. typedef pair<int,int> ii;
  33. typedef long long ll;
  34. ///////////////////////////////////////
  35.  
  36. const ll mod = 1000000007;
  37.  
  38. class BricksN
  39. {
  40. public:
  41.    
  42.     ll dp[60][60];
  43.     ll prec[60];    //prec[i] - сколькими способами можно набрать сумму i
  44.  
  45.     int countStructures(int w, int h, int k)
  46.     {        
  47.         memset(dp,-1,sizeof(dp));
  48.         memset(prec,0,sizeof(prec));
  49.  
  50.         prec[0] = 1;
  51.         for(int i = 0; i < 50; i++)
  52.             for(int d = 1; d <= k; d++)
  53.             {
  54.                 int to = i+d;
  55.                 if(to <= 50)
  56.                     prec[to] = (prec[to]+prec[i])%mod;                    
  57.             }
  58.         ll ans = 0;
  59.         for(int i = 0; i <= h; i++)
  60.             ans = (ans + f(w,i))%mod;
  61.         return int(ans);
  62.     }
  63.  
  64.     ll f(ll w, ll h) //сколькими способами можно набрать высоту РОВНО h при ширине бейсмента w
  65.     {
  66.         if(dp[w][h] == -1)
  67.         {
  68.             if(h == 0 || w == 1)
  69.             {
  70.                 dp[w][h] = 1;
  71.             }
  72.             else if(w == 0)
  73.             {
  74.                 dp[w][h] = 0;
  75.             }
  76.             else
  77.             {
  78.                 dp[w][h] = prec[w]*f(w,h-1)%mod;     //если полностью заполнен нижний уровень
  79.                 dp[w][h] = (dp[w][h]+f(w-1,h))%mod;  //если левая клетка нижнего уровня пуста
  80.  
  81.                 for(int lp = 1; lp < w; lp++)        //перебираем остальные положения самой левой пустой
  82.                                                      // клетки нижнего уровня
  83.                 {
  84.                     ll lb = prec[lp];                //сколькими способами можно заполнить нижний
  85.                                                      //уровень левее пустой клетки
  86.  
  87.                     for(int lh = 1; lh < h; lh++)    //слева высота меньше h, справа ровно h
  88.                     {
  89.                         ll testLeft = lb*f(lp,lh-1);
  90.                         ll testRight = f(w-lp-1,h);
  91.                         dp[w][h] = (dp[w][h] + testLeft*testRight)%mod;
  92.                     }
  93.                     for(int rh = 0; rh <= h; rh++)   //справа высота меньше либо равна h, слева ровно h
  94.                     {
  95.                         ll testLeft = lb*f(lp,h-1);
  96.                         ll testRight = f(w-lp-1,rh);
  97.                         dp[w][h] = (dp[w][h] + testLeft*testRight)%mod;
  98.                     }
  99.                 }
  100.             }
  101.         }
  102.         return dp[w][h];
  103.     }
  104. };
  105.  
  106.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement