標籤: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
35Sample Output範例1
2
範例2
1HINT
資料範圍
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]拯救小矮人