vijos P1020 切蛋糕

来源:互联网 发布:web前端连接数据库 编辑:程序博客网 时间:2024/04/28 18:18
P1020切蛋糕
Accepted
标签:[显示标签]

描述

Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴。他答应给每个人留一口,然后量了量每个人口的大小。Facer有把刀,可以切蛋糕,但他不能把两块蛋糕拼起来,但是他又不会给任何人两块蛋糕。现在问你,facer怎样切蛋糕,才能满足最多的人。(facer的刀很强,切的时候不会浪费蛋糕)。

格式

输入格式

第一行n,facer有n个蛋糕。接下来n行,每行表示一个蛋糕的大小。再一行一个数m,为信息组的人数,然后m行,每行一个数,为一个人嘴的大小。(1<=n<=50, 1<=m<=1024)

输出格式

一行,facer最多可以填多少张嘴巴。

样例1

样例输入1[复制]

4304050251015161718192021252430

样例输出1[复制]

7


/*
1、在输入的时后,记录下面包总面积之和
2、剪去面包不能填到的人
3、只要是在可能填满的人中,用深度遍历搜索
4、若是没有剩余或者与上一次搜索结果相同,则剪枝


*/




#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>


using namespace std;


int cmp(const void *a , const void *b)
{
return ( *(int *)a - *(int *)b) ;
}


int pack[50 + 1] , rail[1024 + 1] , N ,  M ,  total = 0 ,  sumr[1024 + 1] , space ,   Mid ,  bag[50 + 1]; 
// 面包数据  人口数据      面包数 人口数 面包面积总和  人口径之和    剩余量测量深度  面包数据备份
// M-1个的人和  层数


bool Dfsid(int deep , int pos)
{
if (deep <= 0) return true ;
if (space > total - sumr[Mid]) return false ;
for (int i = pos ; i <= N ; i++)
if (bag[i] >= rail[deep])
{
bag[i] -= rail[deep] ;
if (bag[i] < rail[1])
space += bag[i] ;
if (rail[deep] == rail[deep - 1])
{
if (Dfsid(deep - 1 , i)) return true ;
}
else if (Dfsid(deep - 1 , 1)) return true ;
if (bag[i] < rail[1])
space -= bag[i];
bag[i] += rail[deep] ;
}
return false ;
}


int main()
{
int i,len; 
scanf("%d",&N);
for (int i = 1 ; i <= N ; i++)
{
scanf("%d",&pack[i]);
total += pack[i] ;//记录面包的总面积 
}
scanf("%d",&M);
for (int i = 1 ; i <= M ; i++)scanf("%d",&rail[i]);

//快排 
sort(pack,pack+N+1);
sort(rail,rail+M+1); 

for(i=1;i<=M;i++)if(rail[i]>pack[N])break;
len=i-1;

sumr[0] = 0 ;//记录口径的总和
for ( i = 1 ; i <= len ; i++) sumr[i] = sumr[i - 1] + rail[i] ;

while (sumr[len] > total) len--;//剪除不能实现的口径


int Left = 1 , Right = len ;
Mid = ((Left + Right) >> 1 ) ;


while (Left <= Right)
{
for (int i = 1 ; i <= N ; i++) bag[i] = pack[i] ;//备份 
space = 0 ;//清零 
if (Dfsid(Mid , 1))
{
Left = Mid + 1 ;
Mid = ((Left + Right) >> 1);
}
else
{
Right = Mid - 1 ;
Mid = ((Left + Right) >> 1);
}
}
printf("%d\n",Mid);
return 0 ;
}



0 0
原创粉丝点击