描述
旅行者正在为纳西妲准备进行一次关键的突破,以解锁更强大的力量。这次突破需要收集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;
}