Fence Rails 栅栏的木料
农民John 准备建一个栅栏来围住他的牧场.他已经确定了栅栏的形状,但是他在木料方面有些
问题.当地的杂货储存商扔给John 一些木板,而John 必须从这些木板中找出尽可能多所需的木料.
当然,John 可以切木板.因此,一个9 英尺的木板可以切成一个5 英尺和一个4 英尺的木料 (当然也能切成3 个3 英尺的,等等).John 有一把梦幻之锯,因此他在切木料时,不会有木料的损失.
所需要的木料规格都已经给定.你不必切出更多木料,那没有用.
PROGRAM NAME: fence8
INPUT FORMAT
第1 行: N (1 <= N <= 50), 表示提供的木板的数目
第2 行到第N+1 行: N 行,每行包括一个整数,表示各个木板的长度.
第N+2 行: R (1 <= R <= 1023), 所需木料的数目
第N+3 行到第N+R+1 行: R 行,每行一个整数(1 <=Ri <=128),表示所需木料的长度.
SAMPLE INPUT (file fence8.in)
4
30
40
50
25
10
15
16
17
18
19
20
21
25
24
30
OUTPUT FORMAT
只有一行,一个数字,表示能切除的最多的所需木料的树木.当然,并不是任何时候都能切出所
有所需木料.
SAMPLE OUTPUT (file fence8.out)
7
分析:搜索+剪枝
由于答案具有单调性,我们首先二分答案,然后再搜索判断。
显然搜索需要剪枝。
剪枝1:先用大的木板。
剪枝2:若所有废木板(剩余长度<最小木料)之和>最大剩余木板长度,不可行。
剪枝3(我没想到,但貌似非常有用,可能因为R<=1023,Ri<=128,相同木料比较多):将相同的木料编号,小号放在大号前面
这3个剪枝应该足以ac了。
#include
#define ll long long
#define ull unsigned long long
#define inf 2147483647
#define mp make_pair
#define pii pair
#define pb push_back
#define r1 rt<<1
#define r2 rt<<1|1
#define ld long double
using namespace std;
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^'0'),c=getchar();
return x*f;
}
int n,m,a[55],b[1028],s,remain,sum[1028],mid;
inline bool cmp(int x,int y){return x>y;}
bool check(int x,int p){
if(x==0) return 1;
if(remain>s-sum[mid]) return 0;
for(int i=p;i<=n;++i){
if(a[i]>=b[x]){
a[i]-=b[x];
if(a[i]>1;
if(check(mid,1)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}