1 条题解

  • 0
    @ 2026-8-30 1:08:59
    
    //求必须的最小饲料种数,从idx种开始往后遍历
    //没找到一个可行的方案,对比一下是否种类数最小,最小就存起来
    //最后输出ans,ansqueue[]
    
    #include <iostream>
    #include <cstring>
    #include <fstream>
    
    using namespace std;
    
    const int N = 30, M = 25;
    
    int vita[N], vitatmp[N];   //vitatmp存当前的维生素的量,用来判断是否够用
    int g[M][N];
    
    int vitaqueue[M];
    int ansqueue[M];     //用来存放饲料的序号
    int ans = 0x3f;      //记录最小方案的维生素方案种数
    int vis[M];          //是否使用过
    
    int n, m;
    int idx;
    
    bool check()
    {   
        for (int i = 1; i <= n; i++)
            if (vitatmp[i] < vita[i]) return false;
        
        return  true;
    }
    
    void dfs()
    {
        //for (int i = 1; i <= idx; i++) printf("%d ", ansqueue[i]);
        //puts("");
    
    	//这个地方不进行剪枝,数据也能过
        //if (idx > ans || idx > m) return;
    
        if (check())
        {
            //vitatmp够用,但是饲料种数不是最小,就剪枝
            if (idx >= ans) return ;
    
            //暴力搜索,会不断刷新出来优化的方案,存起来
            ans = idx;
            for (int i = 1; i <= ans; i++) ansqueue[i] = vitaqueue[i];
    
            //for (int i = 1; i <= ans; i++) printf("%d ", ansqueue[i]);
            //puts("");
        }
        //如果当前vitatmp还不够用,需要继续去找
    
       for (int i = vitaqueue[idx]; i <= m; i++)
        {
            if (i >= 1 && !vis[i])
            {
                vis[i] = 1;
                vitaqueue[++idx] = i;
                for (int j = 1; j <= n; j++) vitatmp[j] += g[i][j];
    
                dfs();
       
                for (int j = 1; j <= n; j++) vitatmp[j] -= g[i][j];   //j<=n 打成i<=n,调试3小时,溺, bus error 10
                idx--;
                vis[i] = 0;
            }
        }
    
        return ;
    }
    
    
    int main()
    {
        //freopen("P1460_2.in", "r", stdin);
    
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> vita[i];   //vita[]存所需vita标准值
    
        cin >> m;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                cin >> g[i][j];
    
        dfs();
    
        printf("%d ", ans);
        for (int i = 1; i <= ans; i++) printf("%d ", ansqueue[i]);
        puts("");
    
        return 0;
    }
    
    

    总结一下:

    dfs真香

    很多题解用的类似DP,那个解法很好,集合思想

    如果数据很大的时候,可以用二进制进行优化,那就高级了

    MacOS下,第一次遇到 Bus error 10的错误,知道是栈溢出,查了3小时也没整明白。最后用printf大法,打断点看执行过程,一下就揪出了问题(for循环里面i打成了j,溺)

    • 1

    [USACO2.1] 健康的荷斯坦奶牛 Healthy

    信息

    ID
    1003
    时间
    1000ms
    内存
    128MiB
    难度
    9
    标签
    递交数
    8
    已通过
    8
    上传者