洛谷 P1361 小猫爬山
题目描述
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[18000],sum[18000]; int min(int x,int y) { return x>y?y:x; } void dfs(int lc,int Gs) { if(flag) return; if(Gs==n) { flag=1; return; } Gs++; for(int i=1;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=1;i<=n;i++) scanf("%d",&c[i]); while(++Num) { dfs(Num,0); if(flag) { printf("%d",Num); return 0; } } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> bool vis[18000]; int instack[18000],C[18000],cat[18000],cat_ls[18000],N,W,Maxn,leng,Answer; void dfs(int num,int pos,int w) { cat_ls[num]=pos; if(w>Maxn) { for(int k=1;k<=num;k++) cat[k]=cat_ls[k]; Maxn=w; leng=num; } for(int j=pos+1;j<=N;j++) { if(w+C[j]<=W&&instack[j]==0&&!vis[j]) instack[j]=1,dfs(num+1,j,w+C[j]),instack[j]=0; } } int main() { scanf("%d%d",&N,&W); for(int i=1;i<=N;i++) scanf("%d",&C[i]); for(int i=1;i<=N;i++) { if(!vis[i]) { instack[i]=1; Answer++; Maxn=0; dfs(1,i,C[i]); for(int j=1;j<=leng;j++) vis[cat[j]]=1,instack[cat[j]]=0; } } printf("%d",Answer); return 0; }
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。