- 切蛋糕
时间限制 1000 ms 内存限制 128 MB 题目描述 Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴。他答应给每个人留一口,然后量了量每个人口的大小。Facer有把刀,可以切蛋糕,但他不能把两块蛋糕拼起来,但是他又不会给任何人两块蛋糕。现在问你,facer怎样切蛋糕,才能满足最多的人。(facer的刀很强,切的时候不会浪费蛋糕)。
输入数据 第一行 n,facer 有 n 个蛋糕。接下来 n 行,每行表示一个蛋糕的大小。再一行一个数 m, 为信息组的人数,然后 m 行,每行一个数,为一个人嘴的大小。 (1≤n≤50,1≤m≤1024) 输出数据 一行 ,facer 最多可以填多少张嘴巴。 样例输入 4 30 40 50 25 10 15 16 17 18 19 20 21 25 24 30 样例输出 7
其实,我还不太懂,先占个坑吧,之后再多刷几道回溯的题再说
#include<iostream>
#include<algorithm>
#define bug cout<<"no error!";
using namespace std;
int mouth[10000],cake[10000],c[10000],pre[10000],waste,all,n,m,l,r,mid,ans,maxn;
int dfs(int num,int same_start)
{
if(num==0) return 1;
if(all-waste<pre[mid]) return 0;
for(int i=same_start;i<=n;i++)
{
if(c[i]>=mouth[num])
{
c[i]-=mouth[num];
if(c[i]<mouth[1]) waste+=c[i];
if(mouth[num]==mouth[num-1])
{
if(dfs(num-1,i)) return 1;
}
else if(dfs(num-1,1)) return 1;
if(c[i]<mouth[1]) waste-=c[i];
c[i]+=mouth[num];
}
}
return 0;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>cake[i];
all+=cake[i];
if(cake[i]>maxn) maxn=cake[i];
}
cin>>m;
for(int i=1;i<=m;i++)
cin>>mouth[i];
sort(mouth+1,mouth+m+1);
while(maxn<mouth[m]) m--;
for(int i=1;i<=m;i++)
pre[i]=pre[i-1]+mouth[i];
l=0;r=m;
while(l<=r)
{
waste=0;
mid=(l+r)/2;
for(int i=1;i<=n;i++) c[i]=cake[i];
if(dfs(mid,1))
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans;
return 0;
}
这个大佬给了我很多灵感,链接
这个大佬写的很简洁,循序渐进,可以参考 链接2
|