zoukankan      html  css  js  c++  java
  • [SCOI2005]栅栏

    loj题目链接

    洛谷题目链接


    题目描述

    农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材。于是农夫约翰到木材店购买木材。可是木材店老板说他这里只剩下少部分大规格的木板了。不过约翰可以购买这些木板,然后切割成他所需要的规格。而且约翰有一把神奇的锯子,用它来锯木板,不会产生任何损失,也就是说长度为 (10) 的木板可以切成长度为 (8)(2) 的两个木板。

    你的任务:给你约翰所需要的木板的规格,还有木材店老板能够给出的木材的规格,求约翰最多能够得到多少他所需要的木板。

    输入格式

    第一行为整数 (m(mle 50)) 表示木材店老板可以提供多少块木材给约翰。紧跟着 (m) 行为老板提供的每一块木板的长度。

    接下来一行(即第 (m+2) 行)为整数 (n(nle 1000)),表示约翰需要多少木材。

    接下来 (n) 行表示他所需要的每一块木板的长度。木材的规格小于 (32767)。(对于店老板提供的和约翰需要的每块木板,你只能使用一次)。

    输出格式

    只有一行,为约翰最多能够得到的符合条件的木板的个数。

    输入样例

    4
    30
    40
    50
    25
    10
    15
    16
    17
    18
    19
    20
    21
    25
    24
    30
    

    输出样例

    7
    

    dfs+贪心+二分+最优性剪枝+可行性剪枝+排出等效冗余+优化搜索顺序。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    int tmp_g[60],g[60],q[1010],n,m,ans=0,end=0,w,sum=0,s[1010];
    inline int read()
    {
    	int x=0,f=1;
    	char c=getchar();
    	while(c<'0' || c>'9')
    	{
    		if(c=='-') f=-1;
    		c=getchar();
    	}
    	while(c>='0' && c<='9')
    	{
    		x=(x<<1)+(x<<3)+(c^48);
    		c=getchar();
    	}
    	return x*f;
    }
    bool dfs(int st,int step,int k)
    {
    	if(sum-w<s[k]) return false;
    	if(step<=0) return true;
    	for(int i=st;i<=m;i++)
    	{
    		if(g[i]>=q[step])
    		{
    			if(g[i]<q[1]) w+=g[i];
    			g[i]-=q[step]; 
    			if(q[step]==q[step-1])
    			{ 
    				if(dfs(i,step-1,k)) 
    					return true;
    			}
    			else if(dfs(1,step-1,k)) return true;
    			g[i]+=q[step];
    			if(g[i]<q[1]) w-=g[i];
    		}
    	}
    	return false;
    }
    int main()
    {
    	m=read();
    	for(int i=1;i<=m;i++) 
    	{
    		g[i]=read();
    		sum+=g[i];
    	}
    	n=read();
    	for(int i=1;i<=n;i++)
    	{
    		q[i]=read();
    //		s[i]=s[i-1]+q[i];
    	}
    	sort(q+1,q+n+1);
    	for(int i=1;i<=n;i++) s[i]=s[i-1]+q[i]; 
    	while(sum<s[n]) --n; 
    	int l=0,r=n;
    	memcpy(tmp_g,g,sizeof(g));
    	while(l<r)
    	{
    		w=0;
    		memcpy(g,tmp_g,sizeof(tmp_g));
    		int mid=l+r+1>>1;
    		if(dfs(1,mid,mid)) l=mid;
    		else r=mid-1;
    	}
    	printf("%d",l);
    	return 0;
    }
    
  • 相关阅读:
    温故知新 将Date和String类型相互转换
    温故知新 线程
    温故知新 数组
    温故知新 集合
    温故知新 流(字节流与字符流)
    温故知新 jdbc 数据库调取封装
    Reds 持久化 高并发 高可用
    批量修改文件后缀名
    scala之旅-核心语言特性【高阶函数】(十)
    scala之旅-核心语言特性【使用混入组合类】(九)
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/12469213.html
Copyright © 2011-2022 走看看