• 【noip模拟赛5】细菌 状压dp


    【noip模拟赛5】细菌
     

    描述

     

    近期,农场出现了D(1<=D<=15)种细菌。John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶。但是如果选中的奶牛携带了超过 K (1<=K<=D)种不同细菌,所生产的奶就不合格。请你帮助John 计算出最多可以选择多少头奶牛。

    输入

     

    第一行:三个整数N,D,K

    下面N行:第i行表示一头牛所携带的细菌情况。第一个整数di表示这头牛所携带的细菌种类数,后面di个整数表示这些细菌的各自种类标号。

    输出

     

    只一个数 M,最大可选奶牛数。

    输入样例 1 

    6 3 2 
    0
    1 1
    1 2
    1 3
    2 2 1
    2 2 1

    输出样例 1

    5

    提示

    背包(dp)类问题,需要枚举掉所有可能 再算哪个最多。
    但涉及到一个问题,用数组记录的话,可能会爆空间!
     
    存在哪几个病毒,在d最大只有15的情况下,我把用一个int 各位上的0,1 来表示就ok了,相比于用bool记录,还有利于计算。
    所以开两个数组:
    1 a[i]  记录第 i 个奶牛有哪几种病毒 ,比如第m种用 a[i]+=1<<(m-1)  来记录。
    2 dp[i] 病毒情况为 i 时的最大奶牛数。更新n轮(n只奶牛分别枚举)。
     
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <time.h>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #define INF 0x3f3f3f3f
    using namespace std;
    const int N=33010;
    int n,k,d,m,t;
    int a[N],dp[N];
    
    int fun(int x)
    {
        int c=0;
        while(x)
        {
            if(x&1)
                c++;
            x>>=1;
        }
        return c;
    }
    
    int main()
    {
         // freopen("input.txt","r",stdin);
          cin>>n>>d>>k;
          for(int i=0; i<n; i++)
          {
                cin>>t;
                for(int j=0; j<t; j++)
                {
                      cin>>m;
                      a[i]+=1<<(m-1); //状态压缩
                }
          }
          for(int i=0;i<n;i++) // 从 0 到 n-1 枚举每只奶牛
          {
                for(int j=(1<<d)-1;j>0;j--)
                {
                      if(dp[j|a[i]]<dp[j]+1)  //取大
                            dp[j|a[i]]=dp[j]+1;
                }
          }
          int ans=0;
          for(int i=1;i<1<<d;i++)
          {
                if(fun(i)<=k&&dp[i]>ans)
                      ans=dp[i];
          }
          cout<<ans;
          return 0;
    }
  • 相关阅读:
    LeetCode第[84]题(Java):Largest Rectangle in Histogram(最大的矩形柱状图)
    LeetCode第[79]题(Java):Word Search(矩阵单词搜索)
    LeetCode第[78]题(Java):Subsets(求子集)扩展——第[90]题:Subsets 2
    关于SpringMVC中两种映射器不能共存的解决
    LeetCode第[73]题(Java):Set Matrix Zeroes(矩阵置0)
    php分页的实现
    PHP编码规范
    PHP常用函数
    PHP配置文件详解php.ini
    面向对象编程——parent—this
  • 原文地址:https://www.cnblogs.com/zgncbsylm/p/10580326.html
Copyright © 2020-2023  润新知