zoukankan      html  css  js  c++  java
  • SRM 449 div1 (practice)

    250pt:
       暴力枚举所有的可能的情况就好了,求面积的时候我是用梯形的面积减去两个三角形的面积。。
    550pt:
    题意:给你一个蜂窝形状的特殊图形,有一些格子已经被占据了,问你将剩下的格子用1*2的砖块尽可能的铺满的总方案数,见下图。
    
    
    
    
    
    此题想了半天,隐约感觉可以dp,但是无从D起,,,膜拜了下rng_58的超短代码(大部分人选择dfs转移),但是rng_58将图转换成网格后巧妙的使用逐格递推的方法,代码超短,简直就是高端洋气上档次啊,好想又好写,这种题我以前都是dfs写转移的,要,b半天才能写出来。。
    
     #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    class HexagonalBattlefield{
        public :
    int countArrangements(vector <int> X, vector <int> Y, int N) ;
    };
    int g[250][250];
    long long  dp[2][1<<15];
    const int mod =  2000000011;
    void Add(long long &x,int y)
    {
        x += y;
        if(x >= mod) x -= mod;
    }
    int dx[] = {1,0,-1,0,1,-1};
    int dy[] = {0,1,0,-1,1,-1};
    vector<pair<int,int> > p;
    int HexagonalBattlefield::countArrangements(vector <int> X, vector <int> Y, int N)
    {
        N --;
        for(int i = -N; i <= N; i++) {
            for(int j = -N; j <= N; j++) if(abs(i-j)  <= N ){//ddddd
        //    puts("ddd");
                int t = 0;
                for(int k = 0; k < X.size(); k++) {
                    if(i == X[k] && j == Y[k]) {t=1;break;}
                }
                if(!t) p.push_back(make_pair(i,j));
            }
        }
      //  puts("dddd");
        int m = p.size();
        for(int i = 0; i < m; i++) {
            int x = p[i].first , y = p[i].second;
            for(int j = 0; j < 6; j++) {
                int tx = x + dx[j];
                int ty = y + dy[j];
                for(int k = 0; k < m; k++) if(tx == p[k].first && ty == p[k].second) {
                    g[i][k] = true;
                }
            }   
        }
      //  printf("m=%d
    ",m);
       // puts("debug"); 
        int cur = 0, nxt = 1;
        dp[cur][0] = 1;
        for(int i = 0; i < m; i++) {
          // printf("i=%d
    ",i);
            memset(dp[nxt],0,sizeof(dp[nxt]));
            for(int j = 0; j < (1<<15); j++) if(dp[cur][j]){
                if(j&1) {Add(dp[nxt][j>>1] , dp[cur][j]); continue;}
                for(int k = 1; k <= 15; k++) if(i+k < m && g[i][i+k] && !( j&(1<<k) ) ) {
                    int mask = ( j | (1 << k) )>> 1; 
                    Add(dp[nxt][mask] , dp[cur][j]);
                }
            }
            std::swap(cur,nxt);
        }
        return dp[cur][0];
    }
    


    
    
    
    
  • 相关阅读:
    第五届河南省大学生程序设计竞赛 :最强DE战斗力(大数乘法)
    zzuli2455: 最大增区间(一)
    zzuli2455: 最大增区间(一)
    zzuli2424: 越靠近,越幸运(dfs)
    菜根谭#31
    菜根谭#30
    菜根谭#29
    菜根谭#28
    菜根谭#27
    菜根谭#26
  • 原文地址:https://www.cnblogs.com/pangblog/p/3246620.html
Copyright © 2011-2022 走看看