最短突破天数

文章讲述了旅行者需在每天有限的体力条件下,按照材料需求收集稀有材料以助纳西妲突破。提供了两种算法实现:一是贪心策略,二是暴力搜索,目标是最短天数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

旅行者正在为纳西妲准备进行一次关键的突破,以解锁更强大的力量。这次突破需要收集N种稀有材料,这些材料的数量需求分别为C1、C2……CN。旅行者在收集材料的过程中会消耗体力,每获取一份指定的材料,就会消耗与数量相对应的体力点数。

假设提瓦特大陆的现有规则是,每位旅行者每天都会获得W点体力。但是这些体力是宝贵的,因为它们不会累积到下一天,未使用的体力会在每日结束时消失。

并且,对于每一种材料,需在一天时间内全部收集完成(例如,某种材料收集需要80体力,但是当天只剩50体力,则该材料在当天无法完成收集)。

现在,面对这样的挑战,旅行者需要你的帮助来计划他的探险,以确保他可以在最短的天数内收集到所有必需的材料,完成这次关键的突破。

请合理安排探险计划,计算出旅行者帮助纳西妲完成突破所需的最短天数。

对于100%的数据,1<=N<=18,1<=Ci<=W<=10^8。

输入

第一行包含两个用空格隔开的整数,N和W。

接下来N行,每行一个整数,其中第i+1行的整数表示第i种材料的数量Ci。

输出

一个整数表示最短需要的天数

代码实现(贪心):

注意贪心能解决大部分问题,但是仍然有部分测试点过不了

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int C[19]={0};
bool st[19];
int sum=0;
int main()
{
    int N,W;
    cin>>N>>W;
    memset(st,true,N*sizeof(bool));
    for(int i=0;i<N;i++)
    {
        cin>>C[i];
    }
    sort(C,C+N);
    int num=N;
    while(num)
    {
        bool flag=true;
        int t=W;
        for(int i=N-1;i>=0;i--)
        {
            if(st[i])
            {
                if(t>=C[i]){
                flag=false;
                t-=C[i];
                st[i]=false;
                num--;
                }
                else break;
            }
        }
        if(flag)break;
        sum++;
    }
    cout<<sum;
    return  0;
}

代码实现(暴力搜索):

#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 20
int C[MAX]={0};
int power[MAX]={0};
int N,W,res;
bool comp(int a,int b)
{
    return a>b;
}
void read_arr();
void dfs(int,int);
int main()
{
    read_arr();
    dfs(0,0);
    cout<<res<<endl;
    return 0;
}
void read_arr()
{
    cin>>N>>W;
    for(int i=0;i<N;i++)
    {
        cin>>C[i];
    }
    sort(C,C+N,comp);//排序之后可以更快的找到最优解
    res=N;
}
void dfs(int stuff,int day)
{//最多需要N天,暴力搜索每一种可能
    if(day>res)return;
    if(stuff==N)
    {
        res=day;
        return;
    }
    for(int i=0;i<day;i++)
    {
        if(power[i]+C[stuff]<=W)
        {
            power[i]+=C[stuff];
            dfs(stuff+1,day);
            power[i]-=C[stuff];
        }
    }
    power[day]=C[stuff];
    dfs(stuff+1,day+1);
    power[day]=0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值