JZOJ 3804. 【NOIP2014模拟8.24】小X 的AK 计划
Description
在小X 的家鄉(xiāng),有機(jī)房一條街,街上有很多機(jī)房。每個(gè)機(jī)房里都有一萬(wàn)個(gè)人在切題。小X 剛刷完CodeChef,準(zhǔn)備出來(lái)逛逛。
機(jī)房一條街有n 個(gè)機(jī)房,第i 個(gè)機(jī)房的坐標(biāo)為xi,小X 的家坐標(biāo)為0。小X 在街上移動(dòng)的速度為1,即從x1 到x2 所耗費(fèi)的時(shí)間為 |x1?x2|。
每個(gè)機(jī)房的學(xué)生數(shù)量不同,ACM 題目水平也良莠不齊。小X 到達(dá)第i 個(gè)機(jī)房后,可以花ti 的時(shí)間想題,然后瞬間AK;當(dāng)然,也可以過(guò)機(jī)房而不入。
小X 現(xiàn)在只有m 個(gè)單位時(shí)間,之后他就該趕著去打Codeforces 了。現(xiàn)在他想知道自己最多能在多少個(gè)機(jī)房AK,希望你幫幫他。
Input
第一行包含兩個(gè)整數(shù)n;m。
接下來(lái)n 行,每行包含兩個(gè)整數(shù)xi; ti。
Output
第一行包含一個(gè)整數(shù),表示小X 最多能AK 的機(jī)房數(shù)量。
Sample Input
2 10
1 100
5 5
Sample Output
1
Data Constraint
對(duì)于30% 的數(shù)據(jù),n≤20。
對(duì)于60% 的數(shù)據(jù),n≤1000。
對(duì)于100% 的數(shù)據(jù),1≤n≤105,0≤m;xi≤1018,0≤ti≤109。
Solution
這題給人的第一感覺(jué)就是貪心
當(dāng)然首先要按每個(gè)點(diǎn)的坐標(biāo)排序了
顯然他是不可能往回走的
那么很容易想到,當(dāng)他走到一個(gè)點(diǎn) i 時(shí),
只需從 1?n 中選出一些數(shù),使得總和小于等于 m?ti ,讓這些數(shù)的個(gè)數(shù)最多
那么顯然選最小的那幾個(gè),并且使得總和小于等于 m?ti 即可
于是維護(hù)一個(gè)從小到大的 時(shí)間表,每次累加最小并符合條件的那幾個(gè)
維護(hù)時(shí)使用插入排序,時(shí)間復(fù)雜度 O(n2)
但是一看數(shù)據(jù)范圍: n≤105 !!!肯定過(guò)不了~~~
把思路回到維護(hù)時(shí)間表那里,每次插入排序顯然效率超低,又維護(hù)了不少的無(wú)關(guān)量
首先大到使總和超過(guò) m?ti 的那些數(shù)可以直接舍去
剩下的即為要選的,之后當(dāng)遇到一個(gè)時(shí)間 ti 時(shí),
把當(dāng)前要選的數(shù)之中最大的給替換成 ti ,那么答案便最優(yōu)了
這樣累加的時(shí)間復(fù)雜度就是 O(nlogn) !
Code
#include<cstdio> #include<algorithm> using namespace std; const int N=100001; struct data {long long x;int y; }a[N]; int ans,n,f[N]; long long sum,m; inline bool cmp(data a,data b){return a.x<b.x;} int main() {scanf("%d%lld",&n,&m);for(int i=1;i<=n;i++) scanf("%lld%d",&a[i].x,&a[i].y);sort(a+1,a+1+n,cmp);for(int i=1;i<=n;i++)if(sum+a[i].y<=m-a[i].x){sum+=f[++f[0]]=a[i].y;ans++;}elseif(a[i].y<f[f[0]]){sum-=f[f[0]]-a[i].y;f[f[0]]=a[i].y;}printf("%d",ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的JZOJ 3804. 【NOIP2014模拟8.24】小X 的AK 计划的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 线性筛法 与 线性求欧拉函数 的计算模板
- 下一篇: hdu3068 . 最长回文