zoukankan      html  css  js  c++  java
  • 腾讯马拉松复赛第二场

    A 错排公式 d[n] = (n-1)*(d[n-1]+d[n-2]);

    View Code
    #include<stdio.h>
    
    typedef long long LL;
    
    LL d[110];
    const int mod = 1e9+7;
    
    void init(){
        d[1] = 0; d[2] = 1;
        for(int i = 3; i <= 100; i++){
            d[i] = 1LL*(i-1)*(d[i-1]+d[i-2])%mod;        
        }    
    }
    
    int main(){
        init();
        int T; scanf("%d",&T);
        while( T-- ){
            int n;
            scanf("%d", &n);
            printf("%I64d\n", d[n] );    
        }
        return 0;    
    }

    B 每次至少有个国家恐慌值+1,超过5则必定在有限次以内。。。直接暴力BFS/DFS。。

    C ,D 跪了。

      模型一,最大独立点集 , 又 最大团中顶点数量 = 补图中最大独立点数

      可以用优化的 Bron-Kerbosch 算法求解最大团中顶点数量

    View Code
    #include<cstdio>
    #include<cstring>
    #define N 1010
    bool flag[N], a[N][N];
    int ans, cnt[N], group[N], n, vis[N];
    // 最大团: V中取K个顶点,两点间相互连接
    // 最大独立集: V中取K个顶点,两点间不连接 
    // 最大团数量 = 补图中最大独立集数
     
    bool dfs( int u, int pos ){
        int i, j;
        for( i = u+1; i <= n; i++){
            if( cnt[i]+pos <= ans ) return 0;
            if( a[u][i] ){
                 // 与目前团中元素比较,取 Non-N(i) 
                for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break; 
                if( j == pos ){     // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中 
                    vis[pos] = i;
                    if( dfs( i, pos+1 ) ) return 1;    
                }    
            }
        }    
        if( pos > ans ){
                for( i = 0; i < pos; i++ )
                    group[i] = vis[i]; // 最大团 元素 
                ans = pos;
                return 1;    
        }    
        return 0;
    } 
    void maxclique()
    {
        ans=-1;
        for(int i=n;i>0;i--)
        {
            vis[0]=i;
            dfs(i,1);
            cnt[i]=ans;
        }
    }
    int dir[8][2] = { {1,1},{-1,-1},{1,-1},{-1,1}
    ,{2,0},{-2,0},{0,2},{0,-2} };
    int mp[110][11], num[110][11];
    int main(){
        int nn, m;
        while( scanf("%d%d",&nn,&m) != EOF){
            int p = 0;
            memset( num, 0, sizeof(num));
            memset( a, 0, sizeof(a));
            for(int i = 0; i < nn; i++)
                for(int j = 0; j < m; j++){
                    scanf("%d",&mp[i][j]);
                    if( mp[i][j] ) num[i][j] = ++p;    
                }    
            for(int i = 0; i < nn; i++){
                for(int j = 0; j < m; j++){
                    if( mp[i][j] )
                    for(int k = 0; k < 8; k++){
                        int x = i+dir[k][0], y = j+dir[k][1];
                        if( (x>=0)&&(x<nn)&&(y>=0)&&(y<m) && mp[x][y] )
                            a[ num[i][j] ][ num[x][y] ] = a[ num[x][y] ][ num[i][j] ] = 1;
                    }    
                }    
            }
            n = p;
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                if( i == j ) a[i][j] = 0;
                else    a[i][j] ^= 1;  
            maxclique();
            printf("%d\n", ans );
        }
        return 0;    
    } 

      

      模型二,状态压缩DP, 类似题目有 poj1038poj1185

  • 相关阅读:
    每日一题 为了工作 2020 0412 第四十一题
    每日一题 为了工作 2020 04011 第四十题
    每日一题 为了工作 2020 0410 第三十九题
    每日一题 为了工作 2020 0409 第三十八题
    每日一题 为了工作 2020 0408 第三十七题
    每日一题 为了工作 2020 0407 第三十六题
    每日一题 为了工作 2020 0406 第三十五题
    每日一题 为了工作 2020 0405 第三十四题
    学习总结(二十四)
    学习总结(二十三)
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/2991602.html
Copyright © 2011-2022 走看看