题目描述
WD和LHX饲养了N只小猫,这天,小猫们要去爬山。经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下山了。
WD和LHX只好花钱让它们坐索道下山。索道上的缆车最大承重量为W,而N只小猫的重量分别是C1、C2……CN。当然,每辆缆车上的小猫的重量之和不能超过W。每租用一辆缆车,WD和LHX就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?
输入输出格式
输入格式:
第一行包含两个用空格隔开的整数,N和W。
接下来N行每行一个整数,其中第i+1行的整数表示第i只小猫的重量C i。
输出格式:
输出一个整数,最少需要多少美元,也就是最少需要多少辆缆车。
输入输出样例
输入样例#1:
5 1996
1
2
1994
12
29
输出样例#1:
2
说明
数据范围与约定
对于100%的数据,1<=N<=18,1<=C i <=W<=10^8。
搜索回溯 +剪枝 : 把前i只猫放在前i个缆车上
#include <cstdio>
bool flag;
int Num,Sum,n,w,c[],sum[];
int min(int x,int y)
{
return x>y?y:x;
}
void dfs(int lc,int Gs)
{
if(flag) return;
if(Gs==n)
{
flag=;
return;
}
Gs++;
for(int i=;i<=min(lc,Gs);i++)
{
if(sum[i]+c[Gs]<=w)
{
sum[i]=sum[i]+c[Gs];
dfs(lc,Gs);
sum[i]=sum[i]-c[Gs];
}
}
}
int main()
{
scanf("%d%d",&n,&w);
for(int i=;i<=n;i++) scanf("%d",&c[i]);
while(++Num)
{
dfs(Num,);
if(flag)
{
printf("%d",Num);
return ;
}
}
}
#include <cstdio>
bool vis[];
int instack[],C[],cat[],cat_ls[],N,W,Maxn,leng,Answer;
void dfs(int num,int pos,int w)
{
cat_ls[num]=pos;
if(w>Maxn)
{
for(int k=;k<=num;k++) cat[k]=cat_ls[k];
Maxn=w;
leng=num;
}
for(int j=pos+;j<=N;j++)
{
if(w+C[j]<=W&&instack[j]==&&!vis[j]) instack[j]=,dfs(num+,j,w+C[j]),instack[j]=;
}
}
int main()
{
scanf("%d%d",&N,&W);
for(int i=;i<=N;i++) scanf("%d",&C[i]);
for(int i=;i<=N;i++)
{
if(!vis[i])
{
instack[i]=;
Answer++;
Maxn=;
dfs(,i,C[i]);
for(int j=;j<=leng;j++) vis[cat[j]]=,instack[cat[j]]=;
}
}
printf("%d",Answer);
return ;
}
74分贪心代码存档