• USACO 2.14 Healthy Holsteins(BFS)


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

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

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

    输出:

    输出文件只有一行,包括

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

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

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

    分析:总共有十五种饲料,要找出符合能满足条件的最少的种数,相当于要求出一种组合,那么就求出各种长度的组合,再找出符合条件的最小字典序。

    用BFS做的,关键是记录状态,每一个状态要记录几个量

    struct node
    {
     int state;//用位来记录路径,即使用过哪几种饲料
     int ver[26];//保存状态值,
     short cur;//当前选择的编号最大的饲料
     short cnt;//已选择的种类数
    };

    每次取出一种状态时,从当前最大饲料的编号之后开始添加选择的饲料,同时记录下所选择的饲料编号,这样,第一个满足条件就题目所求的。

    以 测试例子为例:

    整个搜索过程是这样的:

    先将这三个状态压入对列 (1)  (2)  (3)

     取出(1)之后,就会分别将(1, 2)  (1,3)

    取出(2)  之后,就会将(2,3)

    取出(3) 之后……

     取出(1,2)之后,就会将(1,2,3)

    取出(1,3)之后,满足条件,退出;

    之后输出就比较简单了;

    /*
    ID: nanke691
    LANG: C++
    TASK: holstein
    */
    #include<iostream>
    #include<fstream>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    using namespace std;
    struct node
    {
    	int state;//用位来记录路径,即使用过哪几种饲料
    	int ver[26];//保存状态值,
    	short cur;//当前选择的编号最大的饲料
    	short cnt;//已选择的种类数
    };
    int hol[20][30];
    int V,G,aim[30],len,ans;
    queue<node> Q;
    bool  compare(int *a)//判断是否符合条件
    {
    	for(int i=1;i<=V;i++)
    		if(a[i]<aim[i])
    			return false;
    	return true;
    }
    void BFS()
    {
    	node s,f;
    	for(int i=1;i<=G;i++)
    	{
    		for(int j=1;j<=V;j++)
    			s.ver[j]=hol[i][j];
    		s.state=(1<<(i-1));
    		s.cur=i;
    		s.cnt=1;
    		Q.push(s);
    	}
    	len=100000000;
    	while(!Q.empty())
    	{
    		f=Q.front();
    		Q.pop();
    		if(f.cnt<=len && compare(f.ver))
    		{
    
    			len=f.cnt;	
    			ans=f.state;
    			break;
    		}
    		for(int i=f.cur+1;i<=G;i++)
    		{
    			for(int j=1;j<=V;j++)
    				s.ver[j]=f.ver[j]+hol[i][j];
    			s.cnt=f.cnt+1;
    			s.cur=i;
    			s.state=(f.state | (1<<(i-1)));//记录下当前选取的编号
    			Q.push(s);
    		}
    	}
    }
    int main()
    {
    	freopen("holstein.in","r",stdin);
    	freopen("holstein.out","w",stdout);
    	scanf("%d",&V);
    	for(int i=1;i<=V;i++)
    		scanf("%d",&aim[i]);
    	scanf("%d",&G);
    	for(int i=1;i<=G;i++)
    		for(int j=1;j<=V;j++)
    			scanf("%d",&hol[i][j]);
    	BFS();
    	cout<<len<<' ';
    	int flag=0;
    	for(int i=1;i<=G;i++)
    	{
    		if((ans &(1<<(i-1)))!=0)
    		{
    			if(!flag)
    			cout<<i,flag=1;
    			else cout<<' '<<i;
    		}
    	}
    	cout<<endl;
    }
    
  • 相关阅读:
    "字符反向拼接"组件:<reverse> —— 快应用组件库H-UI
    "首字母变大写"组件:<capitalize> —— 快应用组件库H-UI
    "字母全变大写"组件:<uppercase> —— 快应用组件库H-UI
    "字母全变小写"组件:<lowercase> —— 快应用组件库H-UI
    "多行文本"组件:<multi> —— 快应用组件库H-UI
    "斜体显示"组件:<i> —— 快应用组件库H-UI
    捕捉AVPlayerViewController 系统原生工具栏的出现、隐藏事件
    (简单实用)Android支付宝商家收款语音播报
    使用wkwebview时,push后,再pop返回,报错
    安卓进度条两边圆角+渐变的拓展
  • 原文地址:https://www.cnblogs.com/nanke/p/2225558.html
Copyright © 2020-2023  润新知