洛谷 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;
        }
    }
}
#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;
}
74分贪心代码存档
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
原文地址:https://www.cnblogs.com/ruojisun/p/6718259.html