【NOIP模拟赛】小猫爬山

Description
Freda和rainbow饲养了N只小猫,这天们要去爬山。经历了千辛万苦,小猫们终于爬上了山顶,但是疲倦的它们再也不想徒步走下(呜咕><><)。
Freda和rainbow只好花钱让它们坐索道下山。索道上的缆车最大承重量为W,而N只小猫的重量分别是 C1、C2…… CN。当然,每辆缆车上的小猫重量之和不能超过W。每 租用一辆缆车,Freda和rainbow就要付1美元,所以他们想知道,最少需要付多少美元才能把这N只小猫都运送下山?

Input
第一行包含两个用空格隔开的整数,N和W。
接下来N行每一个整数,其中第 i+1行的整数表示第i只小猫的重量Ci。

Output
输出 一个整数,最少需要多美元也就是辆缆车 。

Sample Input
5 1996
1
2
1994
12
29

Sample Output
2

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

题解

一看N<=18,马上就想到random_shuffle乱搞,直接统计前缀和然后贪心分组就OK

#include<bits/stdc++.h>
using namespace std;
const long long inf=20000000000;
long long cat[25];
long long sum[25];
long long n,m,tot,ans;
long long read() {
   long long num=0;
   char ch=getchar();
   while(ch>'9'||ch<'0') {
   	ch=getchar();
   }
   while(ch>='0'&&ch<='9') {
   	num=(num<<1)+(num<<3)+ch-'0';
   	ch=getchar();
   }
   return num;
}
int main() {
   n=read(),m=read();
   ans=inf;
   for(int i=1; i<=n; i++) {
   	cat[i]=read();
   }
   for(int i=1; i<=2000; i++) {//i的上限大家自己随便乱搞都行
   	long long m_=m;
   	random_shuffle(cat+1,cat+n+1);
   	for(int j=1; j<=n; j++) {
   		sum[j]=cat[j]+sum[j-1];
   	}
   	sum[n+1]=inf;
   	int x=upper_bound(sum+1,sum+n+1+1,m)-sum;
   	x-=1;
   	if(x==n) {
   		puts("1");
   		return 0;
   	}
   	while(x!=n) {
   		tot++;
   		m=m_+sum[x];
   		x=upper_bound(sum+1,sum+n+1+1,m)-sum;
   		x-=1;
   		if(x==n) {
   			tot++;
   		}
   	}
   	ans=min(ans,tot);
   	tot=0;
   	m=m_;
   }
   printf("%lld",ans);
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值