• 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;
    }



  • 相关阅读:
    WHU-1551-Pairs(莫队算法+分块实现)
    JS日历控件 灵活设置: 精确的时分秒.
    java集群优化——多线程下的单例模式
    课程设计——银行系统
    互联网金融,巨头天下还是创业者天堂?
    Android 使用图片异步载入框架Universal Image Loader的问题
    程序C++ to C#交互
    浅谈asp.net通过本机cookie仿百度(google)实现搜索input框自己主动弹出搜索提示
    全栈JavaScript之路(十六)HTML5 HTMLDocument 类型的变化
    推荐安卓开发神器(里面有各种UI特效和实例)
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6537732.html
Copyright © 2020-2023  润新知