如此水的題竟然讓我絞盡腦汁,我在想我是否是快退役了.
這道題我看見不少解法:貪心,揹包,桶排亂七八糟一大堆.spa
題目描述
又是一年秋季時,陶陶家的蘋果樹結了 n 個果子。陶陶又跑去摘蘋果,此次他有一個 a 公分的椅子。當他手夠不着時,他會站到椅子上再試試。code
此次與 NOIp2005 普及組第一題不一樣的是:陶陶以前搬凳子,力氣只剩下 s 了。固然,每次摘蘋果時都要用必定的力氣。陶陶想知道在 s<0 以前最多能摘到多少個蘋果。排序
如今已知 nn 個蘋果到達地上的高度 x[i],椅子的高度 a,陶陶手伸直的最大長度 b,陶陶所剩的力氣 s,陶陶摘一個蘋果須要的力氣 y[i],求陶陶最多能摘到多少個蘋果。it
輸入格式
第 1 行:兩個數 蘋果數 n,力氣 s。
第 2 行:兩個數 椅子的高度 a,陶陶手伸直的最大長度 b。
第 3 行~第 3+n-1 行:每行兩個數 蘋果高度 x[i],摘這個蘋果須要的力氣 y[i]io
輸出格式
只有一個整數,表示陶陶最多能摘到的蘋果數。class
雖然拿題目來湊篇幅是有一種很不道德的行爲,可是我怕你沒作過這題,因此...嘿嘿.sort
既然他讓咱們求最多能拿多少個蘋果,咱們很容易想到揹包.可是細細一想好像又不是,畢竟他的前輩但是一道大水題,那麼既然他是由前一個題目疊加而做,那麼咱們把它分開求解便可.di
咱們能夠將蘋果分爲兩類,能拿的和不能拿的.
而不能拿的蘋果又有兩類,身高不夠高而不能拿的和體力不夠多而不能拿的.
那麼咱們在一開始讀入的時候就將他們給去掉,能夠節省不少大麻煩,咱們並不用關心那些拿不了的.while
而這樣讀入就有兩種方式:co
int p, m; int x[6000], y[6000]; for(int i = 1; i <= n; i++) { 讀入p和m if(條件符合) x[++cnt1] = p, y[++cnt2] = m;//存入 }
第二種則是用while讀入,
int h = a + b; int t = n; while(t != 0) { scanf("%d%d", &x[k], &y[k]); t--;//讀了一個減一個 if(x[k] > h || y[k] > s)//條件符合 x[k] = y[k] = 0;//清空 else k++;//計數器加一位 }
本人使用第二種,更推薦第一種.
第二步,咱們只須要貪心最小的y[i]就行了,畢竟耗費的體力越少摘得越多嘛~並且這是沒必要擔憂x與y的值會亂掉了,由於咱們不須要再關心x了.
將y排序一邊,體力值減掉,答案加起來.因而這道題就被咱們使用巧妙的模擬解決掉了.
#include <cstdio> #include <algorithm> using namespace std; int n, s, a, b; int k = 1; int x[6000], y[6000]; int ans; int main() { scanf("%d%d%d%d", &n, &s, &a, &b); int h = a + b; int t = n; while(t != 0) { scanf("%d%d", &x[k], &y[k]); t--; if(x[k] > h || y[k] > s) x[k] = y[k] = 0; else k++; } k--; sort(y + 1, y + 1 + k); for(int i = 1; i <= k; i++) { s -= y[i]; if(s >= 0) ans++; else break; } printf("%d", ans); }