zoukankan      html  css  js  c++  java
  • hdu6149 Valley Numer II 分组背包+状态压缩

    /**
    题目:hdu6149 Valley Numer II
    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149
    题意:
    众所周知,度度熊非常喜欢图。
    为了形成山谷,首先要将一个图的顶点标记为高点或者低点。
    标记完成后如果一个顶点三元组<X, Y, Z>中,
    X和Y之间有边,Y与Z之间也有边,同时X和Z是高点,Y是低点,那么它们就构成一个valley。
    度度熊想知道一个无向图中最多可以构成多少个valley,一个顶点最多只能出现在一个valley中。
    ● 1≤T≤20
    ● 1≤N≤30
    ● 1≤M≤N*(N-1)/2
    ● 0≤K≤min(N,15)
    ● 1≤Xi, Yi≤N, Xi!=Yi
    ● 1≤Vi≤N
    思路:由于k最大是15,所以可以分组背包+状态压缩
    
    因为每两个高点和一个低点才能构成一个三元组,k最大15,所以最多7个三元组;
    
    所有的低点作为分组条件。
    每一组存入可以和该低点构成三元组的pair<x,z>,用s表示状态;
    
    dp[i][s]表示放入i体积,高点状态为s可以获得的最多三元组;
    
    dp[i][s] = max(dp[i][s],dp[i-1][s-s1]+1) (s&(s1)==0)
    
    ps:自己老是在这个地方搞错,dp[7][i]这里的第一维要开到8以上!!!
    
    
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <iostream>
    #include <cmath>
    #include <vector>
    #include <map>
    using namespace std;
    typedef long long LL;
    #define ms(x,y) memset(x,y,sizeof x)
    typedef pair<int, int> P;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const int N =10005;
    int dp[8][1<<15];
    vector<int> v[31];
    int f[33][33];
    int gao[33], pos[33];
    vector<int> g;
    int main()
    {
        int T;
        int n, m, k;
        cin>>T;
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            ms(f,0);
            int x, y;
            for(int i = 1; i <= m; i++){
                scanf("%d%d",&x,&y);
                f[x][y] = 1;
                f[y][x] = 1;
            }
            ms(gao,0);
            g.clear();
            for(int i = 1; i <= k; i++){
                scanf("%d",&x);
                pos[x] = i-1;
                g.push_back(x);
                gao[x] = 1;
            }
            for(int i = 1; i<= n; i++) v[i].clear();
            for(int i = 1; i <= n; i++){
                if(gao[i]==0){
                    for(int j = 0; j<g.size();j++){
                        for(int z = j+1; z <g.size(); z++){
                            if(f[i][g[j]]&&f[i][g[z]]){
                                v[i].push_back((1<<pos[g[j]])|(1<<pos[g[z]]));
                            }
                        }
                    }
                }
            }
            memset(dp, -inf, sizeof dp);
            dp[0][0] = 0;
            int len = 1<<k;
            for(int i = 1; i <= n; i++){
                if(gao[i]||(int)v[i].size()==0) continue;
                for(int j = 7; j >= 1; j--){
                    for(int x = 0; x < v[i].size(); x++){
                        for(int y = 0; y < len; y++){
                            if((y&v[i][x])==v[i][x]){
                                dp[j][y] = max(dp[j][y],dp[j-1][y-v[i][x]]+1);
                            }
                        }
                    }
                }
            }
            int mas = 0;
            for(int i = 1; i <= 7; i++){
                for(int j = 0; j < len; j++){
                    mas = max(mas,dp[i][j]);
                }
            }
            printf("%d
    ",mas);
        }
        return 0;
    }
  • 相关阅读:
    几个比较好的IT站和开发库官网
    Win7下Qt5.2中使用OpenGL的glu函数库无法使用的解决方案
    QT5.2 Assistant-设置应用程序图标
    linux下文件编码格式转换方法(gb18030/utf-8)
    QT-进制转换计算器
    QT-图标设置
    QT-make: *** No rule to make target
    QT的exe文件打开显示,无法定位程序***输入点于动态链接库****
    QT工程文件上传Github仓库
    Eclipse中文乱码
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7390995.html
Copyright © 2011-2022 走看看