bzoj3174 [Tjoi2013]拯救小矮人

來源:互聯網
上載者:User

標籤:des   blog   io   ar   os   sp   for   on   資料   

Description

一群小矮人掉進了一個很深的陷阱裡,由於太矮爬不上來,於是他們決定搭一個人梯。即:一個小矮人站在另一小矮人的 肩膀上,知道最頂端的小矮人伸直胳膊可以碰到陷阱口。對於每一個小矮人,我們知道他從腳到肩膀的高度Ai,並且他的胳膊長度為Bi。陷阱深度為H。如果我 們利用矮人1,矮人2,矮人3,。。。矮人k搭一個梯子,滿足A1+A2+A3+....+Ak+Bk>=H,那麼矮人k就可以離開陷阱逃跑了,一 旦一個矮人逃跑了,他就不能再搭人梯了。
我們希望儘可能多的小矮人逃跑, 問最多可以使多少個小矮人逃跑。

Input第一行一個整數N, 表示矮人的個數,接下來N行每一行兩個整數Ai和Bi,最後一行是H。(Ai,Bi,H<=10^5)Output一個整數表示對多可以逃跑多少小矮人Sample Input範例1

2
20 10
5 5
30

範例2
2
20 10
5 5
35
Sample Output範例1
2

範例2
1
HINT

 

資料範圍

30%的資料 N<=200

100%的資料 N<=2000

 首先orz hzwer這題是貪心完dp就是正常做法:已知兩個相鄰的小矮人a和b,考慮交換ab位置的代價首先如果a在b下面,那麼第一次的高度是a.a+b.a+b.b,第二次的高度是a.a+a.b然後如果b在a下面,那麼第一次的高度是a.a+b.a+a.b,第二次的高度是b.a+b.b我們要考慮的就是交換ab會對原來的答案有什麼影響比較直觀的想法是關鍵看第二次的高度,因為第二次的高度更高的那個,最終一定比另一個優。還要考慮可能會出現的第二個比另一個更高但是第一個不如另一個的情況。即可能出現a.a+a.b>b.a+b.b,但是a.a+b.a+b.b<a.a+b.a+a.b,即a.b>a.a+b.b。要知道這是完全可能的考慮在這種情況下,假設a.b>a.a+b.b,那不交換的情況下第一次是a.a+b.a+b.b<a.b+b.a<b.b+a.b+a.a因此交換完還是更優所以只需a.a+a.b<a.a+b.b即可上面我們已經證明按貪心完的順序取是最優的,但是還要確定最多能走掉多少個接下來要dp:令f[i]表示走完i個矮人之後還能取到的最大高度這樣貪心的作用就出來了:按照貪心完的順序取走矮人,可以保證最優。一開始初始化f[0]表示沒有矮人走掉,f[0]=Σa[i]。然後就是枚舉取到第i個矮人,可以用它來更新f[j]的情況是f[j]+ai.b>=m。這樣就可以算出最大值了這題解真TM長……要把貪心講清楚真不容易啊
#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<deque>#include<set>#include<map>#include<ctime>#define LL long long#define inf 0x7ffffff#define pa pair<int,int>#define pi 3.1415926535897932384626433832795028841971using namespace std;inline LL read(){    LL x=0,f=1;char ch=getchar();    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}    return x*f;}inline void write(LL a){if (a<0){printf("-");a=-a;}if (a>=10)write(a/10);putchar(a%10+‘0‘);}struct man{int a,b;}a[100010];inline bool operator <(const man &a,const man &b){return a.a+a.b<b.a+b.b;}int n,lim,ans;int f[100010];int main(){memset(f,-1,sizeof(f));f[0]=0;n=read();for(int i=1;i<=n;i++){a[i].a=read();a[i].b=read();f[0]+=a[i].a;}lim=read();sort(a+1,a+n+1);for (int i=1;i<=n;i++){for (int j=ans;j>=0;j--){if (a[i].b+f[j]>=lim)f[j+1]=max(f[j+1],f[j]-a[i].a);if (f[ans+1]>=0)ans++;}}write(ans);return 0;}

  

bzoj3174 [Tjoi2013]拯救小矮人

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.