zoukankan      html  css  js  c++  java
  • P1460 健康的荷斯坦奶牛 Healthy Holsteins

    P1460 健康的荷斯坦奶牛 Healthy Holsteins


    题目描述

    农民JOHN以拥有世界上最健康的奶牛为傲。他知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。

    给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。

    维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解。

    输入输出格式

    输入格式:

    第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数。

    第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种维他命的最小量。

    第3行:一个整数G(1<=G<=15),表示可用来喂牛的饲料的种数。

    下面G行,第n行表示编号为n饲料包含的各种维他命的量的多少。

    输出格式:

    输出文件只有一行,包括

    牛必需的最小的饲料种数P

    后面有P个数,表示所选择的饲料编号(按从小到大排列)。

    如果有多个解,输出饲料序号最小的(即字典序最小)。

    输入输出样例

    输入样例#1:
    4
    100 200 300 400
    3
    50  50  50  50
    200 300 200 300
    900 150 389 399
    输出样例#1:
    2 1 3
    

    说明

    USACO 2.1

    翻译来自NOCOW


    被卡了一个小时,第一次写剪纸的蒟蒻就是我。


    首先就是要枚举不重复的子集,根据测算,只需要枚举25 +24 +23  +...+1 = (25 + 1)*25/2个子集,所以时间复杂度是相当低的。
    但是如果枚举成25!的子集,一定会崩掉。


    我们为了避免枚举重复的子集,采取了这样的枚举自己方法(紫书里还有一种):

    枚举子集内元素个数1..n,并保证子集是单调递增的。这样就能够补充不漏的枚举子集。

    上代码。


    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    const int MAXN = 25 + 15;
    const int MAXM = 15 + 15;
    
    int n;
    int min[MAXN];
    int m;
    int value[MAXM][MAXN];
    
    int c[MAXN];
    
    int num[MAXN];
    bool b[MAXM];
    
    bool IsFull[MAXN];
    
    int ans;
    
    int cnt;
    bool ok;
    
    void dfs(int step,int pre)
    {
    	if(ok)return;
    	if(step > cnt + 1) return;
    	if(step == cnt + 1)
    	{
    		for(int i = 1;i <= n;i ++)
    		{
    			int sum = 0;
    			for(int j = 1;j <= cnt;j ++)
    			{
    				sum += value[num[j]][i];
    			}
    			if(sum < min[i])return;
    		}
    		ans = cnt;
    		ok  = true;
    		return;
    	}
    
    	for(int i = 1;i <= m;i ++)
    	{
    		if(ok)return;
    		if(i <= pre)continue; 
    		if(!b[i])
    		{
    			num[step] = i;
    			b[i] = true;
    			dfs(step + 1,i);
    			b[i] = false;
    		}
    	}
    }	
    
    int main()
    {
    	freopen("data.txt", "r", stdin);
    	ans = 99999999;
    	scanf("%d", &n);
    	for(int i = 1;i <= n;i ++)
    	{
    		scanf("%d", &min[i]);
    	}
    	scanf("%d", &m);
    	for(int i = 1;i <= m;i ++)
    	{
    		for(int j = 1;j <= n;j ++)
    		{
    			scanf("%d", &value[i][j]);
    		}
    	}
    	for(int i = 1;i <= m;i ++)
    	{
    		cnt ++;
    		dfs(1,0);
    		if(ok) break;
    	}	
    	printf("%d ", ans);
    	for(int i = 1;i <= ans;i ++)
    	{
    		printf("%d ", num[i]);
    	}
    	return 0;
    }



  • 相关阅读:
    游标cursor
    SQL: EXISTS
    LeetCode Reverse Integer
    LeetCode Same Tree
    LeetCode Maximum Depth of Binary Tree
    LeetCode 3Sum Closest
    LeetCode Linked List Cycle
    LeetCode Best Time to Buy and Sell Stock II
    LeetCode Balanced Binary Tree
    LeetCode Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6537732.html
Copyright © 2011-2022 走看看