【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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章