zoukankan      html  css  js  c++  java
  • 深搜入门

    问题描述

    Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) is running through the farm. Farmer John would like to milk as many of his N (1 <= N <= 1,000) cows as possible. If the milked cows carry more than K (1 <= K <= D) different diseases among them, then the milk will be too contaminated and will have to be discarded in its entirety. Please help determine the largest number of cows FJ can milk without having to discard the milk.

    输入

    * Line 1: Three space-separated integers: N, D, and K 

    * Lines 2..N+1: Line i+1 describes the diseases of cow i with a list of 1 or more space-separated integers. The first integer, d_i, is the count of cow i's diseases; the next d_i integers enumerate the actual diseases. Of course, the list is empty if d_i is 0. 

    输出

    * Line 1: M, the maximum number of cows which can be milked.

    样例输入

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

    样例输出

    5
    

    提示

    OUTPUT DETAILS: 

    If FJ milks cows 1, 2, 3, 5, and 6, then the milk will have only two diseases (#1 and #2), which is no greater than K (2). 
    题意:有n头牛 d中病毒 如果牛感染超过k中病毒就视为不健康  求最多有多少头牛是健康的  ( 给你一些集合n,让你从中取一些集合求并,并之后集合的元素个数不能超过k。问你最多取多少集合。)
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int oo = 0x3f3f3f3f;
    const int N = 200;
    const int M = 6000;
    typedef long long LL;
    struct da
    {
        int k;
        int die[50];
        bool operator <(const da &a)const
        {
            return k < a.k;
        }
    }cow[1111];
    int vis[1111], n, D, K, ans, dis[1111];
    void dfs(int x, int sum, int maxs)
    {
        if(sum > K) return ;
        ans = max(ans, maxs);
       // if(x == n+1 && ans < maxs) ans = maxs;
        if(x > n)return ;
    
        for(int i = x; i <= n; i++)
        {
            if(vis[i] == 0)
            {
                vis[i] = 1;
                int cnt = 0;
                for(int j = 1; j <= cow[i].k; j++)
                {
                    if(dis[cow[i].die[j]] == 0)
                        cnt++;
                    dis[cow[i].die[j]]++;
                }
               // if(sum+cnt <= K && maxs+1 > ans) ans = maxs + 1;
                //sum += cnt;
                dfs(i+1, sum+cnt, maxs+1);
                vis[i] = 0;
               // sum -= cnt;
                for(int j = 1; j <= cow[i].k; j++)
                    dis[cow[i].die[j]]--;
            }
        }
        dfs(x+1, sum, maxs);
    }
    int main()
    {
        int i;
        while(~scanf("%d %d %d", &n, &D, &K))
        {
            memset(vis, 0, sizeof(vis));
            memset(dis, 0, sizeof(dis));
            for(i = 1; i <= n; i++)
            {
                scanf("%d", &cow[i].k);
                for(int j = 1; j <= cow[i].k; j++)
                    scanf("%d", &cow[i].die[j]);
            }
            ans = 0;
            sort(cow, cow+n);
            dfs(1, 0, 0);
            printf("%d
    ", ans);
        }
        return 0;
    }
    TLE!!!

    TLE 了之后 借鉴了大神的想法换了种搜索的方式  很巧妙 我竟没想到(当选出的病毒数为K时,就遍历这N头牛,如果有牛所携带的病毒包含在K这些病毒里面  m++) 

    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int oo = 0x3f3f3f3f;
    const int N = 200;
    const int M = 6000;
    typedef long long LL;
    struct da
    {
        int k;
        int die[50];
        bool operator <(const da &a)const
        {
            return k < a.k;
        }
    } cow[1111];
    int vis[1111], n, D, K, ans;
    void solve()
    {
        int i, j, mini = 0;
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= cow[i].k; j++)
            {
                if(!vis[cow[i].die[j]])/**< 如果这头牛所感染的病毒没有出现过 这头牛就不能选 */
                    break;
            }
            if(j == cow[i].k+1) mini++;/**< 这头牛所携带的病毒都出现过 选上这头牛 */
        }
        ans = max(ans, mini);
    }
    void dfs(int x, int sum)
    {
        if(sum == K)solve();
        if(x > D) return ;/**< 递归结束边界 */
        vis[x] = 1;/**< 标记数组 标记这个病毒是否出现过 */
        dfs(x+1, sum+1);
        vis[x] = 0;
        dfs(x+1, sum);
    }
    int main()
    {
        int i;
        while(~scanf("%d %d %d", &n, &D, &K))
        {
            memset(vis, 0, sizeof(vis));
            for(i = 1; i <= n; i++)
            {
                scanf("%d", &cow[i].k);
                for(int j = 1; j <= cow[i].k; j++)
                    scanf("%d", &cow[i].die[j]);
            }
            ans = 0;
            sort(cow, cow+n);/**< 貌似可以不排序 */
            dfs(1, 0);
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    关于Entity Framework中的Attached报错的完美解决方案
    关于C# Winform DataGridView 设置DefaultCellStyle无效的原因与解决方案
    实现winform DataGridView控件判断滚动条是否滚动到当前已加载的数据行底部
    关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要系列文章索引
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要五
    C# Winform 通过FlowLayoutPanel及自定义的编辑控件,实现快速构建C/S版的编辑表单页面
    NPOI导入导出EXCEL通用类,供参考,可直接使用在WinForm项目中
    阅读《LEARNING HARD C#学习笔记》知识点总结与摘要四
    C#实现通用数据过滤窗体
  • 原文地址:https://www.cnblogs.com/PersistFaith/p/4819914.html
Copyright © 2011-2022 走看看